6 |
7 |
--------------------------------------------------------------------------------
/markdownapp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "docservertomarkdown",
3 | "version": "0.4.2",
4 | "author": "Dave Winer {
20 | "title": "Scripting News",
21 | "description": "It's even worse than it appears.",
22 | "pubDate": "2021-11-17T18:40:46.000Z",
23 | "link": "http://oldschool.scripting.com/davewiner/",
24 | "language": "en-us",
25 | "copyright": "copyright 1994-2021 Dave Winer.",
26 | "generator": "oldSchool v0.7.12",
27 | "cloud": {
28 | "domain": "rpc.rsscloud.io",
29 | "port": "5337",
30 | "path": "/pleaseNotify",
31 | "registerprocedure": "",
32 | "protocol": "http-post",
33 | "type": "rsscloud"
34 | },
35 | "items": [
36 | {
37 | "description": "New verb coming soon in Drummer, rss.readFeed. It takes the URL of an RSS feed, and returns a JavaScript object containg the information in the feed in an easy-to-use format (for programmers of course).",
38 | "pubDate": "2021-11-19T18:30:39.000Z",
39 | "link": "http://scripting.com/2021/11/19.html#a183039",
40 | "guid": "http://scripting.com/2021/11/19.html#a183039"
41 | },
42 | {
43 | "description": "I missed the renewal notices for the Radio3.io domain, so it's out now, but I expect it'll be back shortly. Sorry! :-(",
44 | "pubDate": "2021-11-19T17:38:44.000Z",
45 | "link": "http://scripting.com/2021/11/19.html#a173844",
46 | "guid": "http://scripting.com/2021/11/19.html#a173844"
47 | },
48 | {
49 | "description": "A discussion about how Markdown should be processed for Drummer blogs. Basically, what role if any should indentation play, and how many newlines to generate for each line in the outline. My current position -- indentation should play no role in the Markdown we generate from the outline, it should be ignored. And we should generate one newline for every line in the outline. Note this is not how Drummer works now.",
50 | "pubDate": "2021-11-19T15:16:46.000Z",
51 | "link": "http://scripting.com/2021/11/19.html#a151646",
52 | "guid": "http://scripting.com/2021/11/19.html#a151646"
53 | },
54 | {
55 | "description": "I did a refresh on the ArtShow collection yesterday, a few hundred more classic paintings. Free to download, or use via web.",
56 | "pubDate": "2021-11-18T12:14:39.000Z",
57 | "link": "http://scripting.com/2021/11/18.html#a121439",
58 | "guid": "http://scripting.com/2021/11/18.html#a121439"
59 | },
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/docs/pages/drummer.md:
--------------------------------------------------------------------------------
1 |
2 | # drummer verbs
3 | ## drummer.productname
4 | #### Syntax
5 | drummer.productname ()
6 |
7 | #### Params
8 | None
9 |
10 | #### Returns
11 | The name of the Drummer app.
12 |
13 | #### Notes
14 | At first it might seem silly to have a verb that tells your script the name of the Drummer app, but these things do change sometimes.
15 |
16 | For example, there was a scripting language in the Fargo app, and it's possible someone might run one of its scripts here.
17 |
18 | fargo.version is implemented here, so you can find out that this isn't Fargo anymore, if your script cares.
19 |
20 | When you've been doing this for a long time, the value of these kinds of hooks become apparent.
21 |
22 | #### Examples
23 | `drummer.productname ()`
24 |
25 | - *"drummer"*
26 |
27 | ## drummer.productnameForDisplay
28 | #### Syntax
29 | drummer.productnameForDisplay ()
30 |
31 | #### Params
32 | None
33 |
34 | #### Returns
35 | The name of the Drummer app in a form suitable for displaying in a dialog, or other kind of message to the user.
36 |
37 | #### Examples
38 | `drummer.productnameForDisplay ()`
39 |
40 | - *"Drummer"*
41 |
42 | ## drummer.runScript
43 | #### Syntax
44 | drummer.runScript (string)
45 |
46 | #### Params
47 | The string is a bit of JavaScript code.
48 |
49 | #### Returns
50 | undefined.
51 |
52 | #### Notes
53 | The script text runs but I was hoping the value would be returned, but it's not.
54 |
55 | In the second example below, nothing happens.
56 |
57 | #### Examples
58 | `drummer.runScript ("dialog.alert (\"Hello World\")")`
59 |
60 | - *undefined*
61 |
62 | `drummer.runScript ("100 * 12")`
63 |
64 | - *undefined*
65 |
66 | ## drummer.subscribeToOutline
67 | #### Syntax
68 | drummer.subscribeToOutline (string)
69 |
70 | #### Params
71 | The string is the URL of an OPML file.
72 |
73 | #### What it does
74 | The outline opens in a new tab, or if it's already open, Drummer brings the tab to the front.
75 |
76 | #### Returns
77 | true.
78 |
79 | #### Notes
80 | If the outline has a <urlUpdateSocket> head element, Drummer will request updates from the server, and will automatically update the outline when the outline changes.
81 |
82 | See the instantOutlines project for examples and code for this protocol.
83 |
84 | #### Examples
85 | `drummer.subscribeToOutline ("http://scripting.com/states.opml")`
86 |
87 | - *true*
88 |
89 | ## drummer.version
90 | #### Syntax
91 | drummer.version ()
92 |
93 | #### Params
94 | None
95 |
96 | #### Returns
97 | The current version of the Drummer software.
98 |
99 | #### Examples
100 | `drummer.version ()`
101 |
102 | - *2.0.6*
103 |
104 | ## drummer.useStylesheet
105 | #### Syntax
106 | drummer.useStylesheet (string)
107 |
108 | #### Params
109 | The string is the URL of an CSS style sheet file.
110 |
111 | #### What it does
112 | Applies the style sheet to Drummer.
113 |
114 | #### Returns
115 | true.
116 |
117 | #### Notes
118 | We're using this Stack Overflow piece as guidance.
119 |
120 | #### Example
121 | `drummer.useStylesheet ("http://scripting.com/misc/darkmodestyles.css")`
122 |
123 | - *true*
124 |
125 |
--------------------------------------------------------------------------------
/docs/pages/oldSchool.md:
--------------------------------------------------------------------------------
1 |
2 | # oldSchool verbs
3 | ## oldSchool.buildBlog
4 | #### Syntax
5 | oldSchool.buildBlog (boolean)
6 |
7 | #### Params
8 | The boolean, which is options, says whether or not you want all the data returned by Old School to be returned by this verb.
9 |
10 | #### What it does
11 | Calls drummercms.scripting.com telling it to build the user's Old School blog.
12 |
13 | #### Returns
14 | The web address of the user's blog if the boolean is false, otherwise all the data Old School returns in the form of a JavaScript object.
15 |
16 | #### Example
17 | `oldSchool.buildBlog ()`
18 |
19 | - *http://oldschool.scripting.com/cluelessnewbie/*
20 |
21 | `oldSchool.buildBlog (true)`
22 |
23 | {
24 | "baseUrl": "http://clueless.lucky.wtf/",
25 | "ctSecs": 1.199,
26 | "oldSchoolVersion": "0.7.9",
27 | "eventLog": {
28 | "pagesPublished": [
29 | "2021/10/30/174131.html",
30 | "2021/10/30/152252.html",
31 | "2021/10/30.html",
32 | "index.html",
33 | "homepage.html",
34 | "rss.json",
35 | "fb/rss.xml",
36 | "index.json"
37 | ],
38 | "pingsSent": [
39 | {
40 | "urlServer": "http://rpc.rsscloud.io:5337/ping",
41 | "urlFeed": "http://clueless.lucky.wtf/rss.json"
42 | },
43 | {
44 | "urlServer": "http://rpc.rsscloud.io:5337/ping",
45 | "urlFeed": "http://clueless.lucky.wtf/fb/rss.xml"
46 | }
47 | ]
48 | },
49 | "headLevelAtts": {
50 | "dateCreated": "Mon, 09 Aug 2021 16:53:40 GMT",
51 | "flPublic": "true",
52 | "urlPublic": "http://oldschool.scripting.com/cluelessnewbie/",
53 | "description": "Searching for clues, so far no luck.",
54 | "urlHeaderImage": "http://scripting.com/images/2020/10/05/sky.png",
55 | "copyright": "copyright 2021 Dave Winer",
56 | "titlex": "I don't have a clue",
57 | "title": "No clues",
58 | "urlGlossary": "http://scripting.com/publicfolder/misc/glossary.opml",
59 | "urlLinkblogJson": "http://radio3.io/users/davewiner/linkblog.json",
60 | "urlAboutOpml": "http://drummer.scripting.com/cluelessnewbie/about.opml",
61 | "urlBlogWebsite": "http://clueless.lucky.wtf/",
62 | "timeZoneOffset": "-5",
63 | "urlTemplate": "http://scripting.com/code/drummercms/templates/minimal/index.html",
64 | "ownerTwitterScreenName": "cluelessnewbie",
65 | "ownerName": "Clueless Newbie",
66 | "ownerId": "http://twitter.com/cluelessnewbie",
67 | "urlUpdateSocket": "ws://drummer.scripting.com:1232/",
68 | "dateModified": "Sun, 31 Oct 2021 15:07:36 GMT",
69 | "expansionState": "1,2,8,13,14",
70 | "lastCursor": "12",
71 | "generator": "opmlPackage v0.4.9"
72 | }
73 | }
74 |
75 | ## oldSchool.getCursorLink
76 | #### Syntax
77 | oldSchool.getCursorLink ()
78 |
79 | #### Params
80 | None.
81 |
82 | #### Returns
83 | The URL of the rendering of the bar cursor headline, if it's part of a blog.
84 |
85 | The file must have a head-level urlBlogWebsite attribute, if not oldSchool.getCursorLink returns undefined.
86 |
87 | If the cursor points into a titled post, the URL points to the specific line in the post the cursor points to.
88 |
89 | #### Note
90 | This functionality is wired into the Eye icon.
91 |
92 | #### Example
93 | `oldSchool.getCursorLink ()`
94 |
95 | - *http://clueless.lucky.wtf/2021/11/14.html#a232957*
96 |
97 |
--------------------------------------------------------------------------------
/docs/pages/tab.md:
--------------------------------------------------------------------------------
1 |
2 | # tab verbs
3 | ## tab.getActiveTabStatus
4 | #### Syntax
5 | tab.getActiveTabStatus ()
6 |
7 | #### Params
8 | None.
9 |
10 | #### Returns
11 | A JavaScript object containing information about the file in the active tab.
12 |
13 | #### Note
14 | This is the actual internal information Drummer uses to keep track of the tab.
15 |
16 | #### Values
17 | flActive -- will always be true.
18 |
19 | name -- the title of the file.
20 |
21 | fname -- the file name, in Electric Drummer, the full path to the file.
22 |
23 | flInstantOutline -- true if it's an instant outline.
24 |
25 | flReadOnly -- true for instant outlines, false for outlines you create.
26 |
27 | flLocked -- applies to instant outlines. True if the outline is locked, which means updates won't be displayed until the user unlocks the file.
28 |
29 | flPrivate -- true if the file is private.
30 |
31 | serialnum -- a unique number assigned to this tab by Drummer.
32 |
33 | #### Examples
34 | `tab.getActiveTabStatus ()`
35 |
36 | {
37 | "flActive": true,
38 | "name": "Scratchpad",
39 | "fname": "scratchpad.opml",
40 | "flReadOnly": false,
41 | "flInstantOutline": false,
42 | "serialnum": 3,
43 | "flLocked": false,
44 | "flPrivate": true
45 | }
46 |
47 | `tab.getActiveTabStatus ().fname`
48 |
49 | - */Users/davewiner/docserver source/verbDocs.opml*
50 |
51 | `file.getFileInfo (tab.getActiveTabStatus ().fname)`
52 |
53 | {
54 | "size": 81644,
55 | "whenAccessed": "2022-01-06T21:00:09.000Z",
56 | "whenCreated": "2021-07-30T13:35:09.000Z",
57 | "whenModified": "2022-01-06T21:19:05.000Z",
58 | "flPrivate": true
59 | }
60 |
61 | ## tab.getPublicUrl
62 | #### Syntax
63 | tab.getPublicUrl () returns string
64 |
65 | #### What it does
66 | If the outline in the current tab in the outliner is public, returns the HTTP address of the file.
67 |
68 | If the outline is private, returns undefined.
69 |
70 | #### Returns
71 | A web address or undefined.
72 |
73 | #### Example
74 | `dialog.alert (tab.getPublicUrl ())`
75 |
76 | - *undefined*
77 |
78 | ## tab.openFile
79 | #### Syntax
80 | tab.openFile (string, string)
81 |
82 | #### Params
83 | The first string is the name of an existing outline file.
84 |
85 | The second string is optional, it's the title you want to appear in the tab. If not specified, the outline's title is displayed in the tab.
86 |
87 | #### What it does
88 | If the file is already open in a tab, that tab comes to the front. If not, and the file exists, it opens in a new tab.
89 |
90 | #### Returns
91 | true
92 |
93 | #### Common error
94 | The file does not exist.
95 |
96 | #### Examples
97 | `tab.openFile ("hello3.opml") `
98 |
99 | - *true*
100 |
101 | `tab.openFile ("hello3.opml", "My Favorite File") `
102 |
103 | - *true*
104 |
105 | ## tab.openInstantOutline
106 | #### Syntax
107 | tab.openInstantOutline (string, string)
108 |
109 | #### Params
110 | The first string is the URL of an instant outline descriptor file.
111 |
112 | The second string is optional, it's the title you want to appear in the tab. If not specified, the outline's title is displayed in the tab.
113 |
114 | #### What it does
115 | If the outline is already open in a tab, that tab comes to the front. If not, and the file exists, it opens in a new tab.
116 |
117 | #### Returns
118 | true.
119 |
120 | #### Bug
121 | It has no way to report an error, if it couldn't open the outline, it still returns true.
122 |
123 | #### Examples
124 | `tab.openInstantOutline ("http://instantoutliner.com/o0", "The states outline") `
125 |
126 | - *true*
127 |
128 |
--------------------------------------------------------------------------------
/docs/pages/http.md:
--------------------------------------------------------------------------------
1 |
2 | # http verbs
3 | ## http.client
4 | #### Syntax
5 | http.client (options, boolean)
6 |
7 | #### Parameters
8 | options is a JavaScript structure that defines the request.
9 |
10 | boolean indicates whether it uses a proxy server (true) or the request is made from the browser (false).
11 |
12 | #### Returns
13 | What the HTTP request returns.
14 |
15 | #### Breakage
16 | There will be breakage. If you want to use this now, be prepared to adjust your code later, and participate in the thread on the RFC site. As long as this alert is here, assume your apps that use this verb will break.
17 |
18 | #### Notes
19 | This is meant to be a complete HTTP client that's accessible to Drummer programmers.
20 |
21 | In its first release in November 2021, it is far from complete. But it gives you a lot more power than the simpler http.readUrl. Most important probably is that http.client can do requests other than GET.
22 |
23 | The options struct is what you would pass to a jQuery AJAX call. Here's a list of values it looks for:
24 |
25 | - *type -- the HTTP method, such as GET, POST, HEAD. *
26 |
27 | - *url -- the address the request is directed to*
28 |
29 | - *data -- the data that is passed in the body of the request. *
30 |
31 | - *params -- a JavaScript object containing the search params for the request. *
32 |
33 | There's a new endpoint in daveappserver that acts as the proxy server for this verb. It is deployed at drummer.scripting.com.
34 |
35 | It's named after the Frontier verb tcp.httpClient, which had a very long param list. In this version I opted for a struct instead. The intention is to do all that the Frontier verb does in this verb, in Drummer.
36 |
37 | #### Examples
38 | `http.client ({url: "http://drummer.scripting.com/now"}, true)`
39 |
40 | - *Fri Nov 05 2021 13:05:15 GMT-0400 (Eastern Daylight Time)*
41 |
42 | ## http.readUrl
43 | #### Syntax
44 | http.readUrl (string, boolean)
45 |
46 | #### Parameters
47 | The string is the http address of the page you want to read.
48 |
49 | The boolean indicates whether you want to go through a proxy server for the request. It's optional, and it's default value is true.
50 |
51 | #### Returns
52 | It makes an HTTP request and returns to the caller what the request returns.
53 |
54 | #### Notes
55 | If you want to access a resource on the local machine, or one that is inaccessible to drummer.scripting.com for some reason, you must not use the proxy server.
56 |
57 | If you can make the request without using the proxy server it will be faster, and conserves resources.
58 |
59 | #### Examples
60 | `http.readUrl ("http://scripting.com/rss.xml", false).length`
61 |
62 | - *73700*
63 |
64 | `http.readUrl ("http://scripting.com/rss.xml", false).length`
65 |
66 | - *73700*
67 |
68 | `http.readUrl ("http://localhost:1410/now", false)`
69 |
70 | - *Mon Aug 09 2021 16:35:28 GMT-0400 (Eastern Daylight Time)*
71 |
72 | ## http.derefUrl
73 | #### Syntax
74 | http.derefUrl (string)
75 |
76 | #### Parameters
77 | The string is a shortened http address. In other words and address that points to another address.
78 |
79 | #### Returns
80 | If the address is not a shortened url, it returns the address itself. If it is, it returns the address that it points to.
81 |
82 | #### Notes
83 | 9/17/2021 by DW -- it does not work in the case that the address is not a shortened url. Not sure why, no time to investigate at this time.
84 |
85 | #### Examples
86 | `http.derefUrl ("https://tinyurl.com/yvfkvaps")`
87 |
88 | - *http://scripting.com/*
89 |
90 | `http.derefUrl ("https://scripting.com/")`
91 |
92 | - *http://scripting.com/*
93 |
94 |
--------------------------------------------------------------------------------
/webapp/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | 83 | [%outlineJson%] 84 |85 |
86 |87 |
88 |89 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /docs/pages/date.md: -------------------------------------------------------------------------------- 1 | 2 | # date verbs 3 | ## date.convertToTimeZone 4 | #### Syntax 5 | date.convertToTimeZone (date, string) 6 | 7 | #### Params 8 | The date param is the date you want to convert to a different time zone. 9 | 10 | The string says how far from GMT and in what direction the other time zone is. For example -5 would be the string for the east coast of the United States, meaning five hours earlier than GMT. "0" is GMT. This param is optional, if not specified it is "0". 11 | 12 | The string param does not have to represent a whole hour. For example Central Indian Time is "+5:30". 13 | 14 | #### Returns 15 | The date, expressed in the indicated time zone. 16 | 17 | If x is a date returned by this routine, you can use the JavaScript date functions to get components of a time, getHours, getMinutes, etc and they will return the correct values for the indicated time zone. 18 | 19 | This is a core routine for building blogs that might be published by software running in a time zone different from the author of the blog. 20 | 21 | #### Examples 22 | `date.convertToTimeZone (clock.now (), "+5:30").toLocaleString ()` 23 | 24 | - *11/15/2021, 8:45:29 PM* 25 | 26 | ## date.dayGreaterThanOrEqual 27 | #### Syntax 28 | date.dayGreaterThanOrEqual (d1, d2) 29 | 30 | #### Params 31 | Both parameters are JavaScript date objects. 32 | 33 | #### Returns 34 | true if the first date is on the same day as the second, or if the first date is later than the second. 35 | 36 | #### Notes 37 | This verb is useful in determining which version of software you're running, if you have the publication date of a new version. Also useful to see if a timer has expired. 38 | 39 | #### Example 40 | `date.dayGreaterThanOrEqual (clock.now (), "November 22, 2018")` 41 | 42 | - *true* 43 | 44 | ## date.netStandardString 45 | #### Syntax 46 | date.netStandardString (date) 47 | 48 | #### Params 49 | date is a JavaScript date object. 50 | 51 | #### Returns 52 | A RFC 822 version of the date. 53 | 54 | #### Notes 55 | This is the format that's required for RSS feeds, OPML files and mail protocols. 56 | 57 | It's a human and machine readable way of expressing of dates. 58 | 59 | #### Examples 60 | `date.netStandardString (clock.now ())` 61 | 62 | - *Sun, 14 Mar 2021 16:28:56 GMT* 63 | 64 | `date.netStandardString ("12/5/97; 9:03:15 PM")` 65 | 66 | - *Sat, 06 Dec 1997 04:03:15 GMT* 67 | 68 | ## date.sameDay 69 | #### Syntax 70 | date.sameDay (d1, d2) 71 | 72 | #### Params 73 | Both parameters are JavaScript date objects. 74 | 75 | #### Returns 76 | true if the dates are on the same day, false otherwise. 77 | 78 | #### Examples 79 | `date.sameDay ("March 12, 2021", "February 12, 2021")` 80 | 81 | - *false* 82 | 83 | `date.sameDay ("March 12, 2021", "March 12, 2021")` 84 | 85 | - *true* 86 | 87 | ## date.sameMonth 88 | #### Syntax 89 | date.sameMonth (d1, d2) 90 | 91 | #### Params 92 | Both parameters are JavaScript date objects. 93 | 94 | #### Returns 95 | true if the dates are in the same month, false otherwise. 96 | 97 | #### Examples 98 | `date.sameMonth ("March 12, 2021", "February 12, 2021")` 99 | 100 | - *false* 101 | 102 | `date.sameMonth ("March 12, 2021", "March 30, 2021")` 103 | 104 | - *true* 105 | 106 | ## date.secondsSince 107 | #### Syntax 108 | date.secondsSince (date) 109 | 110 | #### Params 111 | date is a JavaScript date object. 112 | 113 | #### Returns 114 | The number of seconds since the date. 115 | 116 | #### Notes 117 | Useful when you want to know how long something took. 118 | 119 | #### Example 120 | `date.secondsSince ("March 14, 2020")` 121 | 122 | - *31580389.57* 123 | 124 | ## date.tomorrow 125 | #### Syntax 126 | date.tomorrow (date) 127 | 128 | #### Params 129 | date is a JavaScript date object. 130 | 131 | #### Returns 132 | The result of adding 24 hours from the date. 133 | 134 | #### Example 135 | `date.tomorrow (clock.now ())` 136 | 137 | - *Mon Mar 15 2021 12:21:22 GMT-0400 (Eastern Daylight Time)* 138 | 139 | ## date.yesterday 140 | #### Syntax 141 | date.yesterday (date) 142 | 143 | #### Params 144 | date is a JavaScript date object. 145 | 146 | #### Returns 147 | The result of subtracting 24 hours from the date. 148 | 149 | #### Example 150 | `date.yesterday (clock.now ())` 151 | 152 | - *Sat Mar 13 2021 11:21:02 GMT-0500 (Eastern Standard Time)* 153 | 154 | -------------------------------------------------------------------------------- /docs/pages/daytona.md: -------------------------------------------------------------------------------- 1 | 2 | # daytona verbs 3 | ## daytona.ping 4 | #### Syntax 5 | daytona.ping (urlOutline, collection) 6 | 7 | #### Params 8 | The first param is the URL of a public outline containing the content you want to be included in your Daytona index. 9 | 10 | The second param is optional and defaults to "drummeruser." For most users that's the only value that will work. 11 | 12 | #### What it does 13 | Queues an indexing of the outline. It will usually take a minute or more for Daytona to index the outline. 14 | 15 | #### Returns 16 | A message saying it worked, if it did. 17 | 18 | #### Note 19 | Simply updating the outline is enough to get it to be reindexed, so in most cases you will not have to do the ping from a script. 20 | 21 | #### Example 22 | `daytona.ping ("http://drummer.scripting.com/cluelessnewbie/blog.opml")` 23 | 24 | - *all is good* 25 | 26 | ## daytona.query 27 | #### Syntax 28 | daytona.query (query, collection) 29 | 30 | #### Params 31 | The first param is a string that contains the string you want to search for. 32 | 33 | The second param is the collection you want to search in. It can be scriptingnews, drummerdocs or drummeruser. It's optional, if not present the default value is drummeruser. 34 | 35 | #### Returns 36 | The result of the query in a JavaScript object. 37 | 38 | #### Example 39 | `daytona.query ("BBC")` 40 | 41 |
[
42 | {
43 | "urloutline": "http://drummer.scripting.com/cluelessnewbie/blog.opml",
44 | "whencreated": "2021-12-05T17:11:16.000Z",
45 | "screenname": "cluelessnewbie",
46 | "title": "I'm doing another test!",
47 | "collection": "drummeruser",
48 | "jstruct": {
49 | "text": "I'm doing another test!",
50 | "created": "Sun, 05 Dec 2021 17:11:16 GMT",
51 | "type": "outline",
52 | "subs": [
53 | {
54 | "text": "Like a rolling stone",
55 | "created": "Sun, 05 Dec 2021 22:16:43 GMT"
56 | },
57 | {
58 | "text": "Like the FBI",
59 | "created": "Sun, 05 Dec 2021 22:17:33 GMT"
60 | },
61 | {
62 | "text": "And the CIA",
63 | "created": "Sun, 05 Dec 2021 22:17:36 GMT"
64 | },
65 | {
66 | "text": "BBC",
67 | "created": "Sun, 05 Dec 2021 22:17:39 GMT"
68 | },
69 | {
70 | "text": "BB King",
71 | "created": "Sun, 05 Dec 2021 22:17:40 GMT"
72 | },
73 | {
74 | "text": "And Doris Day",
75 | "created": "Sun, 05 Dec 2021 22:17:44 GMT"
76 | },
77 | {
78 | "text": "Buzz be",
79 | "created": "Sun, 05 Dec 2021 22:17:47 GMT"
80 | },
81 | {
82 | "text": "Buzz be",
83 | "created": "Sun, 05 Dec 2021 22:17:51 GMT"
84 | },
85 | {
86 | "text": "That was can you digit by xxx",
87 | "created": "Sun, 05 Dec 2021 22:17:53 GMT"
88 | },
89 | {
90 | "text": "Now we'd like to sing all the angels come",
91 | "created": "Sun, 05 Dec 2021 22:18:01 GMT"
92 | }
93 | ]
94 | }
95 | }
96 | ]
97 |
98 | ## daytona.resetMyIndex
99 | #### Syntax
100 | daytona.resetMyIndex (collection)
101 |
102 | #### Param
103 | The param is the collection you want to search in. It can be scriptingnews, drummerdocs or drummeruser. It's optional, if not present the default value is drummeruser. For most users, the only value that will work is drummeruser.
104 |
105 | #### Returns
106 | true
107 |
108 | #### What it does
109 | Deletes all index entries for the indicated collection. You're basically saying you want to start over with the index. Then you can either make changes to the outlines you want to include in the index to get them re-indexed, or use the daytona.ping verb.
110 |
111 | #### Note
112 | daytona.removeOutlineRefs is more selective, it only removes references to one outline, not all of them.
113 |
114 | #### Example
115 | `daytona.resetMyIndex ()`
116 |
117 | - *true*
118 |
119 | ## daytona.removeOutlineRefs
120 | #### Syntax
121 | daytona.removeOutlineRefs (urlOutline, collection)
122 |
123 | #### Params
124 | The first param is the address of the public outline that you want removed from your Daytona index.
125 |
126 | The second param is the collection you want it removed from. It can be scriptingnews, drummerdocs or drummeruser. It's optional, if not present the default value is drummeruser.
127 |
128 | #### What it does
129 | Deletes all index entries for the indicated outline, so you can start over with the outline. We will do this with our blog.opml files when we archive the outline, removing all index references for the blog.opml file. If you don't, there will be double-references for posts that were archived, and even worse the ones that come from blog.opml won't be there if you click through the Eye icon to see the context.
130 |
131 | #### Returns
132 | true
133 |
134 | #### Example
135 | `daytona.removeOutlineRefs ("http://drummer.scripting.com/cluelessnewbie/blog.opml")`
136 |
137 | - *true*
138 |
139 |
--------------------------------------------------------------------------------
/markdownapp/docservertomarkdown.js:
--------------------------------------------------------------------------------
1 | const myVersion = "0.4.2", myProductName = "docservertomarkdown";
2 |
3 | var urlDocsOpml = "http://drummer.scripting.com/davewiner/verbDocs.opml";
4 |
5 | const fs = require ("fs");
6 | const utils = require ("daveutils");
7 | const request = require ("request");
8 | const opml = require ("opml");
9 | const davegithub = require ("davegithub");
10 |
11 | var config = {
12 | flUploadToGithub: false,
13 | flGenerateLocalFiles: true,
14 |
15 | localFolder: "", //set in config.json
16 |
17 | username: "scripting",
18 | repo: "docServer",
19 | repoPath: "docs/",
20 |
21 | githubPassword: "",
22 |
23 | baseRepoUrl: "https://github.com/scripting/docServer/blob/main/docs/",
24 |
25 | "committer": {
26 | "name": "Dave Winer",
27 | "email": "dave@scripting.com"
28 | },
29 | "message": ".",
30 |
31 | "userAgent": "docservertomarkdown"
32 | };
33 |
34 | function httpRequest (url, callback) {
35 | request (url, function (err, response, data) {
36 | if (err) {
37 | callback (err);
38 | }
39 | else {
40 | if (response.statusCode != 200) {
41 | const message = "The request returned a status code of " + response.statusCode + ".";
42 | callback ({message});
43 | }
44 | else {
45 | callback (undefined, data)
46 | }
47 | }
48 | });
49 | }
50 | function uploadToGithub (relpath, data, type, callback) {
51 | if (config.flUploadToGithub) {
52 | const options = {
53 | username: config.username,
54 | repo: config.repo,
55 | repoPath: config.repoPath + relpath,
56 | password: config.githubPassword,
57 | data: data,
58 | type: (type === undefined) ? "text/plain" : type,
59 | committer: config.committer,
60 | message: config.message,
61 | userAgent: config.userAgent
62 | };
63 | davegithub.uploadFile (options, function (err, response, body) {
64 | console.log ("uploadToGithub: url == " + config.baseRepoUrl + relpath + ", status == " + response.statusCode);
65 | if (err) {
66 | console.log ("uploadToGithub: err.message == " + err.message);
67 | }
68 | if (callback !== undefined) {
69 | callback ();
70 | }
71 | });
72 | }
73 | else {
74 | callback ();
75 | }
76 | }
77 | function writeLocalFile (relpath, data, callback) {
78 | if (config.flGenerateLocalFiles) {
79 | var f = config.localFolder + relpath;
80 | utils.sureFilePath (f, function () {
81 | fs.writeFile (f, data, function (err) {
82 | console.log ("writeToLocalFile: f == " + f);
83 | if (err) {
84 | console.log ("writeToLocalFile: err.message == " + err.message);
85 | }
86 | if (callback !== undefined) {
87 | callback ();
88 | }
89 | });
90 | });
91 | }
92 | else {
93 | if (callback !== undefined) {
94 | callback ();
95 | }
96 | }
97 | }
98 | function getCategoryFilename (theCategory) {
99 | return (utils.stringNthField (theCategory.text, " ", 1) + ".md");
100 | }
101 | function uploadOneCategory (theCategory, callback) {
102 | var mdtext = "", indentlevel = 0;
103 | function add (s) {
104 | mdtext += s + "\n";
105 | }
106 | function exampleResultToMarkdown (theExampleResult) {
107 | let mdtext = "", indentlevel = 0;
108 | function add (s) {
109 | mdtext += utils.filledString (" ", indentlevel) + s +"\n";
110 | }
111 | function addNode (theNode, flSinglespace=false) {
112 | add (theNode.text);
113 | if (theNode.subs !== undefined) {
114 | for (var i = 0; i < theNode.subs.length; i++) {
115 | indentlevel++;
116 | addNode (theNode.subs [i]);
117 | indentlevel--;
118 | }
119 | }
120 | }
121 | addNode (theExampleResult);
122 | return (mdtext);
123 | }
124 | opml.expandInclude (theCategory, function (err, cat) {
125 | if (err) {
126 | console.log ("uploadOneCategory: err.message == " + err.message);
127 | }
128 | else {
129 | if (cat.subs !== undefined) {
130 | add ("");
131 | add ("# " + theCategory.text);
132 | for (var j = 0; j < cat.subs.length; j++) {
133 | var verb = cat.subs [j];
134 | add ("## " + verb.text);
135 | for (var k = 0; k < verb.subs.length; k++) {
136 | var subtopic = verb.subs [k];
137 | var flCodeSubs = (subtopic.text == "Example") || (subtopic.text == "Examples");
138 | add ("#### " + subtopic.text);
139 | for (var m = 0; m < subtopic.subs.length; m++) {
140 | var line = subtopic.subs [m], linetext = line.text;
141 | if (flCodeSubs) {
142 | linetext = "`" + linetext + "`";
143 | }
144 | add (linetext + "\n");
145 | if (line.subs !== undefined) {
146 | for (var n = 0; n < line.subs.length; n++) {
147 | var exampleresult = line.subs [n];
148 | if (exampleresult.subs === undefined) { //the usual case, a one-line value was returned
149 | add ("- *" + exampleresult.text + "*\n");
150 | }
151 | else {
152 | add ("" + exampleResultToMarkdown (exampleresult) + ""); 153 | } 154 | } 155 | } 156 | } 157 | } 158 | } 159 | } 160 | 161 | var path = "pages/" + getCategoryFilename (theCategory); 162 | uploadToGithub (path, mdtext, undefined, function () { 163 | writeLocalFile (path, mdtext, function () { 164 | callback (); 165 | }); 166 | }); 167 | } 168 | }); 169 | } 170 | function uploadAllCategories (theOutline, callback) { 171 | var theCats = theOutline.opml.body.subs; 172 | function doNext (ix) { 173 | if (ix < theCats.length) { 174 | uploadOneCategory (theCats [ix], function () { 175 | doNext (ix + 1); 176 | }); 177 | } 178 | else { 179 | callback (); 180 | } 181 | } 182 | doNext (0); 183 | } 184 | function uploadIndex (theOutline, callback) { 185 | var mdtext = "", indentlevel = 0; 186 | function add (s) { 187 | mdtext += utils.filledString (" ", indentlevel) + s + "\n"; 188 | } 189 | var theCats = theOutline.opml.body.subs; 190 | add ("# Complete list of verbs"); 191 | 192 | function doNext (ix) { 193 | if (ix < theCats.length) { 194 | var fname = getCategoryFilename (theCats [ix]); 195 | opml.expandInclude (theCats [ix], function (err, cat) { 196 | if (err) { 197 | console.log ("uploadIndex: err.message == " + err.message); 198 | } 199 | else { 200 | if (cat.subs !== undefined) { 201 | for (var j = 0; j < cat.subs.length; j++) { 202 | var verb = cat.subs [j]; 203 | var url = "pages/" + fname + "#" + utils.stringLower (verb.name); 204 | add ("* [" + verb.text + "](" + url + ")"); 205 | } 206 | } 207 | } 208 | doNext (ix + 1); 209 | }); 210 | } 211 | else { 212 | var path = "readme.md"; 213 | uploadToGithub (path, mdtext, undefined, function () { 214 | writeLocalFile (path, mdtext, function () { 215 | callback (); 216 | }); 217 | }); 218 | } 219 | } 220 | doNext (0); 221 | 222 | } 223 | function readConfig (f, theConfig, callback) { 224 | fs.readFile (f, function (err, jsontext) { 225 | if (!err) { 226 | try { 227 | var jstruct = JSON.parse (jsontext); 228 | for (var x in jstruct) { 229 | theConfig [x] = jstruct [x]; 230 | } 231 | } 232 | catch (err) { 233 | console.log ("readConfig: err.message == " + err.message); 234 | } 235 | } 236 | callback (); 237 | }); 238 | } 239 | 240 | readConfig ("config.json", config, function () { 241 | console.log ("config == " + utils.jsonStringify (config)); 242 | httpRequest (urlDocsOpml, function (err, opmltext) { 243 | if (err) { 244 | console.log (err.message); 245 | } 246 | else { 247 | opml.parse (opmltext, function (err, theOutline) { 248 | if (err) { 249 | console.log (err.message); 250 | } 251 | else { 252 | uploadAllCategories (theOutline, function () { 253 | uploadIndex (theOutline, function () { 254 | console.log (""); //skip line 255 | }); 256 | }) 257 | } 258 | }); 259 | } 260 | }) 261 | }); 262 | -------------------------------------------------------------------------------- /docs/readme.md: -------------------------------------------------------------------------------- 1 | # Complete list of verbs 2 | * [base64.encode](pages/base64.md#base64encode) 3 | * [base64.decode](pages/base64.md#base64decode) 4 | * [clock.now](pages/clock.md#clocknow) 5 | * [clock.waitSeconds](pages/clock.md#clockwaitseconds) 6 | * [date.convertToTimeZone](pages/date.md#dateconverttotimezone) 7 | * [date.dayGreaterThanOrEqual](pages/date.md#datedaygreaterthanorequal) 8 | * [date.netStandardString](pages/date.md#datenetstandardstring) 9 | * [date.sameDay](pages/date.md#datesameday) 10 | * [date.sameMonth](pages/date.md#datesamemonth) 11 | * [date.secondsSince](pages/date.md#datesecondssince) 12 | * [date.tomorrow](pages/date.md#datetomorrow) 13 | * [date.yesterday](pages/date.md#dateyesterday) 14 | * [daytona.ping](pages/daytona.md#) 15 | * [daytona.query](pages/daytona.md#) 16 | * [daytona.resetMyIndex](pages/daytona.md#) 17 | * [daytona.removeOutlineRefs](pages/daytona.md#) 18 | * [dialog.alert](pages/dialog.md#dialogalert) 19 | * [dialog.ask](pages/dialog.md#dialogask) 20 | * [dialog.confirm](pages/dialog.md#dialogconfirm) 21 | * [dialog.about](pages/dialog.md#dialogabout) 22 | * [dns.getDomainName](pages/dns.md#dnsgetdomainname) 23 | * [dns.getDottedId](pages/dns.md#dnsgetdottedid) 24 | * [drummer.productname](pages/drummer.md#drummerproductname) 25 | * [drummer.productnameForDisplay](pages/drummer.md#drummerproductnamefordisplay) 26 | * [drummer.runScript](pages/drummer.md#drummerrunscript) 27 | * [drummer.subscribeToOutline](pages/drummer.md#drummersubscribetooutline) 28 | * [drummer.version](pages/drummer.md#drummerversion) 29 | * [drummer.useStylesheet](pages/drummer.md#drummerusestylesheet) 30 | * [file.exists](pages/file.md#fileexists) 31 | * [file.writeWholeFile](pages/file.md#filewritewholefile) 32 | * [file.readWholeFile](pages/file.md#filereadwholefile) 33 | * [file.delete](pages/file.md#filedelete) 34 | * [file.getFileInfo](pages/file.md#filegetfileinfo) 35 | * [file.makeFilePublic](pages/file.md#filemakefilepublic) 36 | * [file.getFileHierarchy](pages/file.md#filegetfilehierarchy) 37 | * [github.connectViaOauth](pages/github.md#githubconnectviaoauth) 38 | * [github.disconnect](pages/github.md#githubdisconnect) 39 | * [github.download](pages/github.md#githubdownload) 40 | * [github.getAccessToken](pages/github.md#githubgetaccesstoken) 41 | * [github.getDirectory](pages/github.md#githubgetdirectory) 42 | * [github.getUserInfo](pages/github.md#githubgetuserinfo) 43 | * [github.upload](pages/github.md#githubupload) 44 | * [http.client](pages/http.md#httpclient) 45 | * [http.readUrl](pages/http.md#httpreadurl) 46 | * [http.derefUrl](pages/http.md#httpderefurl) 47 | * [oldSchool.buildBlog](pages/oldSchool.md#oldschoolbuildblog) 48 | * [oldSchool.getCursorLink](pages/oldSchool.md#oldschoolgetcursorlink) 49 | * [op.attributes.addGroup](pages/op.md#) 50 | * [op.attributes.deleteOne](pages/op.md#) 51 | * [op.attributes.exists](pages/op.md#) 52 | * [op.attributes.getAll](pages/op.md#) 53 | * [op.attributes.getOne](pages/op.md#) 54 | * [op.attributes.makeEmpty](pages/op.md#) 55 | * [op.attributes.setOne](pages/op.md#) 56 | * [op.bold](pages/op.md#) 57 | * [op.collapseEverything](pages/op.md#) 58 | * [op.collapse](pages/op.md#) 59 | * [op.countSubs](pages/op.md#) 60 | * [op.deleteSubs](pages/op.md#) 61 | * [op.demote](pages/op.md#) 62 | * [op.expandAllLevels](pages/op.md#) 63 | * [op.expand](pages/op.md#) 64 | * [op.expandTo](pages/op.md#) 65 | * [op.firstSummit](pages/op.md#) 66 | * [op.getCursorJstruct](pages/op.md#) 67 | * [op.getCursorOpml](pages/op.md#) 68 | * [op.getCursor](pages/op.md#) 69 | * [op.getLineText](pages/op.md#) 70 | * [op.getOutlineJstruct](pages/op.md#) 71 | * [op.getRenderMode](pages/op.md#) 72 | * [op.getSelectedText](pages/op.md#) 73 | * [op.go](pages/op.md#) 74 | * [op.hasSubs](pages/op.md#) 75 | * [op.insertInCalendar](pages/op.md#) 76 | * [op.insertOpml](pages/op.md#) 77 | * [op.insert](pages/op.md#) 78 | * [op.isComment](pages/op.md#) 79 | * [op.italic](pages/op.md#) 80 | * [op.link](pages/op.md#) 81 | * [op.makeComment](pages/op.md#) 82 | * [op.promote](pages/op.md#) 83 | * [op.reorg](pages/op.md#) 84 | * [op.replaceSelectedText](pages/op.md#) 85 | * [op.runSelection](pages/op.md#) 86 | * [op.setCursor](pages/op.md#) 87 | * [op.setLineText](pages/op.md#) 88 | * [op.setRenderMode](pages/op.md#) 89 | * [op.setTextMode](pages/op.md#) 90 | * [op.strikethrough](pages/op.md#) 91 | * [op.toggleComment](pages/op.md#) 92 | * [op.toggleRenderMode](pages/op.md#) 93 | * [op.visitAll](pages/op.md#) 94 | * [op.visitSubs](pages/op.md#) 95 | * [op.visitToSummit](pages/op.md#) 96 | * [opml.parse](pages/opml.md#opmlparse) 97 | * [opml.stringify](pages/opml.md#opmlstringify) 98 | * [opml.attributes.addGroup](pages/opml.md#opmlattributesaddgroup) 99 | * [opml.attributes.deleteOne](pages/opml.md#opmlattributesdeleteone) 100 | * [opml.attributes.exists](pages/opml.md#opmlattributesexists) 101 | * [opml.attributes.getAll](pages/opml.md#opmlattributesgetall) 102 | * [opml.attributes.getOne](pages/opml.md#opmlattributesgetone) 103 | * [opml.attributes.makeEmpty](pages/opml.md#opmlattributesmakeempty) 104 | * [opml.attributes.setAll](pages/opml.md#opmlattributessetall) 105 | * [opml.attributes.setOne](pages/opml.md#opmlattributessetone) 106 | * [opml.getCurrentObject](pages/opml.md#opmlgetcurrentobject) 107 | * [opml.getCurrentOpml](pages/opml.md#opmlgetcurrentopml) 108 | * [opml.getMarkdown](pages/opml.md#opmlgetmarkdown) 109 | * [opml.getHeaders](pages/opml.md#opmlgetheaders) 110 | * [opml.setHeaders](pages/opml.md#opmlsetheaders) 111 | * [rss.readFeed](pages/rss.md#rssreadfeed) 112 | * [speaker.beep](pages/speaker.md#speakerbeep) 113 | * [string.addCommas](pages/string.md#stringaddcommas) 114 | * [string.addPeriodAtEnd](pages/string.md#stringaddperiodatend) 115 | * [string.beginsWith](pages/string.md#stringbeginswith) 116 | * [string.bumpUrlString](pages/string.md#stringbumpurlstring) 117 | * [string.contains](pages/string.md#stringcontains) 118 | * [string.countFields](pages/string.md#stringcountfields) 119 | * [string.dayOfWeekToString](pages/string.md#stringdayofweektostring) 120 | * [string.decodeXml](pages/string.md#stringdecodexml) 121 | * [string.delete](pages/string.md#stringdelete) 122 | * [string.encodeHtml](pages/string.md#stringencodehtml) 123 | * [string.endsWith](pages/string.md#stringendswith) 124 | * [string.extensionToMimeType](pages/string.md#stringextensiontomimetype) 125 | * [string.filledString](pages/string.md#stringfilledstring) 126 | * [string.formatDate](pages/string.md#stringformatdate) 127 | * [string.getRandomPassword](pages/string.md#stringgetrandompassword) 128 | * [string.hashMD5](pages/string.md#stringhashmd5) 129 | * [string.innerCaseName](pages/string.md#stringinnercasename) 130 | * [string.insert](pages/string.md#stringinsert) 131 | * [string.isAlpha](pages/string.md#stringisalpha) 132 | * [string.isNumeric](pages/string.md#stringisnumeric) 133 | * [string.isPunctuation](pages/string.md#stringispunctuation) 134 | * [string.isWhitespace](pages/string.md#stringiswhitespace) 135 | * [string.lastField](pages/string.md#stringlastfield) 136 | * [string.lower](pages/string.md#stringlower) 137 | * [string.maxStringLength](pages/string.md#stringmaxstringlength) 138 | * [string.markdownProcess](pages/string.md#stringmarkdownprocess) 139 | * [string.mid](pages/string.md#stringmid) 140 | * [string.monthToString](pages/string.md#stringmonthtostring) 141 | * [string.multipleReplaceAll](pages/string.md#stringmultiplereplaceall) 142 | * [string.nthField](pages/string.md#stringnthfield) 143 | * [string.padWithZeros](pages/string.md#stringpadwithzeros) 144 | * [string.popExtension](pages/string.md#stringpopextension) 145 | * [string.popLastField](pages/string.md#stringpoplastfield) 146 | * [string.popTrailing](pages/string.md#stringpoptrailing) 147 | * [string.randomSnarkySlogan](pages/string.md#stringrandomsnarkyslogan) 148 | * [string.replaceAll](pages/string.md#stringreplaceall) 149 | * [string.stripMarkup](pages/string.md#stringstripmarkup) 150 | * [string.trimLeading](pages/string.md#stringtrimleading) 151 | * [string.trimTrailing](pages/string.md#stringtrimtrailing) 152 | * [string.trimWhitespace](pages/string.md#stringtrimwhitespace) 153 | * [string.upper](pages/string.md#stringupper) 154 | * [tab.getActiveTabStatus](pages/tab.md#) 155 | * [tab.getPublicUrl](pages/tab.md#tabgetpublicurl) 156 | * [tab.openFile](pages/tab.md#tabopenfile) 157 | * [tab.openInstantOutline](pages/tab.md#tabopeninstantoutline) 158 | * [twitter.addGroupToList](pages/twitter.md#) 159 | * [twitter.addMemberToList](pages/twitter.md#) 160 | * [twitter.getFollowed](pages/twitter.md#twittergetfollowed) 161 | * [twitter.getFollowers](pages/twitter.md#) 162 | * [twitter.getHomeTimeline](pages/twitter.md#) 163 | * [twitter.getListInfo](pages/twitter.md#) 164 | * [twitter.getListMembers](pages/twitter.md#) 165 | * [twitter.getMentionsTimeline](pages/twitter.md#) 166 | * [twitter.getMyScreenname](pages/twitter.md#) 167 | * [twitter.getRawUserInfo](pages/twitter.md#) 168 | * [twitter.getScreenname](pages/twitter.md#) 169 | * [twitter.getThread](pages/twitter.md#) 170 | * [twitter.getTweet](pages/twitter.md#) 171 | * [twitter.getUserLists](pages/twitter.md#) 172 | * [twitter.getUserInfo](pages/twitter.md#) 173 | * [twitter.getUserTimeline](pages/twitter.md#) 174 | * [twitter.newPost](pages/twitter.md#) 175 | * [twitter.removeGroupFromList](pages/twitter.md#) 176 | * [twitter.removeUserFromList](pages/twitter.md#) 177 | * [twitter.updateListInfo](pages/twitter.md#) 178 | * [webBrowser.openUrl](pages/webBrowser.md#webbrowseropenurl) 179 | -------------------------------------------------------------------------------- /docs/pages/file.md: -------------------------------------------------------------------------------- 1 | 2 | # file verbs 3 | ## file.exists 4 | #### Syntax 5 | file.exists (path) 6 | 7 | #### Params 8 | path points to a file in the remote file system. 9 | 10 | #### Action 11 | Determines if the file exists 12 | 13 | #### Returns 14 | True if it exists, false otherwise 15 | 16 | #### Notes 17 | If you try to read a file that doesn't exist, for example, your script will fail. If your application can work even if a file doesn't exist, then you should use this verb to see if it exists. 18 | 19 | #### Examples 20 | `file.exists ("prefs.json")` 21 | 22 | `file.exists ("meaningOfLife.js")` 23 | 24 | ## file.writeWholeFile 25 | #### Syntax 26 | file.writeWholeFile (path, text) 27 | 28 | #### What it does 29 | Creates a new private file, or overwrites an existing file, at the indicated path, with the contents of the second parameter. It creates any folders needed to store the file if they don't exist. 30 | 31 | #### Returns 32 | true. 33 | 34 | #### Note 35 | Files are, by default, private. If you want to create a public file, first create the private file then call file.makeFilePublic. 36 | 37 | #### Examples 38 | `file.writeWholeFile ("hello.txt", "Hello World")` 39 | 40 | - *true* 41 | 42 | `file.writeWholeFile ("code/alert.js", "dialog.alert ('Yo')") ` 43 | 44 | - *true* 45 | 46 | ## file.readWholeFile 47 | #### Syntax 48 | file.readWholeFile (path) 49 | 50 | #### What it does 51 | Reads the file at the indicated path and returns its contents as a string. 52 | 53 | #### Returns 54 | The contents of the file, as a string. 55 | 56 | #### Example 57 | `file.readWholeFile ("hello.txt") ` 58 | 59 | - *Hello World* 60 | 61 | ## file.delete 62 | #### Syntax 63 | file.delete (path) 64 | 65 | #### What it does 66 | Tries to delete both a private file or a public one at the indicated path. It's an error if neither file exists. 67 | 68 | #### Returns 69 | undefined 70 | 71 | #### Example 72 | `file.writeWholeFile ("deleteme.txt", "It's even worse than it appears.")` 73 | 74 | - *true* 75 | 76 | `file.readWholeFile ("deleteme.txt")` 77 | 78 | - *It's even worse than it appears.* 79 | 80 | `file.delete ("deleteme.txt")` 81 | 82 | - *undefined* 83 | 84 | ## file.getFileInfo 85 | #### Syntax 86 | file.getFileInfo (path) 87 | 88 | #### Params 89 | path is a string, the location to a file being stored on the server. 90 | 91 | #### Returns 92 | Information about the file, including: its size in bytes, when it was created, last read, last modified, and whether it's public or private. 93 | 94 | If the file is public, urlPublic, the address of the file, is included. 95 | 96 | #### Example 97 | `file.getFileInfo ("states.opml") ` 98 | 99 |
{
100 | "size": 2741,
101 | "whenAccessed": "2021-08-24T14:51:15.000Z",
102 | "whenCreated": "2021-08-24T14:51:15.000Z",
103 | "whenModified": "2021-08-24T14:56:13.000Z",
104 | "flPrivate": false,
105 | "urlPublic": "http://drummer.scripting.com/cluelessnewbie/states.opml"
106 | }
107 |
108 | `file.getFileInfo ("scratchpad.opml")`
109 |
110 | {
111 | "size": 85332,
112 | "whenAccessed": "2021-08-24T14:48:53.000Z",
113 | "whenCreated": "2021-07-30T13:35:09.000Z",
114 | "whenModified": "2021-08-24T14:58:31.000Z",
115 | "flPrivate": true
116 | }
117 |
118 | ## file.makeFilePublic
119 | #### Syntax
120 | file.makeFilePublic (path)
121 |
122 | #### What it does
123 | Makes the file public if it is private.
124 |
125 | #### Returns
126 | The public URL of the file.
127 |
128 | #### Example
129 | `file.makeFilePublic ("hello.txt")`
130 |
131 | - *http://drummer.scripting.com/davewiner/hello.txt*
132 |
133 | `http.readUrl ("http://drummer.scripting.com/davewiner/hello.txt")`
134 |
135 | - *Hello World*
136 |
137 | ## file.getFileHierarchy
138 | #### Syntax
139 | file.getFileHierarchy ()
140 |
141 | #### What it does
142 | Returns a JavaScript object that describes the user's file hierarchy.
143 |
144 | There are two top-level branches, Private files and Public files. Unless you have explicitly made a file public, all files are private.
145 |
146 | Under each is the hierarchy, as they are stored in the file system on the server. For each folder there is a whenCreated and a whenModified value, and an object called subs, which contains the files and any sub-folders.
147 |
148 | For each file, in addition to creation and modification dates, ctChars is the size of the file.
149 |
150 | #### Returns
151 | A JavaScript object as explained above.
152 |
153 | #### Notes
154 | This feature is based on the folderToJson package.
155 |
156 | And the Outline file hierarchy command in the Tools menu is built on file.getFileHierarchy.
157 |
158 | #### Example
159 | `file.getFileHierarchy ()`
160 |
161 | {
162 | "publicFiles": {
163 | "subs": {
164 | "april2021Status.opml": {
165 | "ctChars": 21475,
166 | "whenCreated": "2021-05-17T01:46:17.385Z",
167 | "whenModified": "2021-05-17T01:46:17.385Z"
168 | },
169 | "aprilMayDrummerChanges.opml": {
170 | "ctChars": 15657,
171 | "whenCreated": "2021-05-17T01:40:27.646Z",
172 | "whenModified": "2021-05-17T01:41:56.446Z"
173 | },
174 | "daveStatus.opml": {
175 | "ctChars": 39467,
176 | "whenCreated": "2021-05-06T22:34:17.160Z",
177 | "whenModified": "2021-05-29T16:13:19.181Z"
178 | },
179 | "february2021Status.opml": {
180 | "ctChars": 70491,
181 | "whenCreated": "2021-05-17T01:43:24.202Z",
182 | "whenModified": "2021-05-17T01:43:24.202Z"
183 | },
184 | "hello.txt": {
185 | "ctChars": 11,
186 | "whenCreated": "2021-05-29T16:08:07.954Z",
187 | "whenModified": "2021-05-29T16:12:06.257Z"
188 | },
189 | "march2021Status.opml": {
190 | "ctChars": 51300,
191 | "whenCreated": "2021-05-17T01:45:09.122Z",
192 | "whenModified": "2021-05-17T01:45:09.298Z"
193 | },
194 | "opVerbDocs.opml": {
195 | "ctChars": 56658,
196 | "whenCreated": "2021-05-16T19:39:17.747Z",
197 | "whenModified": "2021-05-17T01:38:28.054Z"
198 | },
199 | "scratchpad.json": {
200 | "ctChars": 14558,
201 | "whenCreated": "2021-05-28T15:16:10.378Z",
202 | "whenModified": "2021-05-29T15:05:52.017Z"
203 | },
204 | "scratchpad.opml": {
205 | "ctChars": 7290,
206 | "whenCreated": "2021-05-28T15:16:10.330Z",
207 | "whenModified": "2021-05-29T15:05:51.973Z"
208 | },
209 | "twitterVerbDocs.json": {
210 | "ctChars": 135024,
211 | "whenCreated": "2021-05-28T16:16:08.924Z",
212 | "whenModified": "2021-05-28T18:10:22.472Z"
213 | },
214 | "twitterVerbDocs.opml": {
215 | "ctChars": 51601,
216 | "whenCreated": "2021-05-07T15:03:13.106Z",
217 | "whenModified": "2021-05-28T18:10:22.296Z"
218 | },
219 | "undefined": {
220 | "ctChars": 5491,
221 | "whenCreated": "2021-05-15T15:12:46.388Z",
222 | "whenModified": "2021-05-28T15:51:14.558Z"
223 | },
224 | "verbDocs.opml": {
225 | "ctChars": 111226,
226 | "whenCreated": "2021-05-07T20:15:45.464Z",
227 | "whenModified": "2021-05-17T01:38:45.546Z"
228 | }
229 | }
230 | },
231 | "privateFiles": {
232 | "subs": {
233 | "april2021Status.opml": {
234 | "ctChars": 21475,
235 | "whenCreated": "2021-05-17T01:45:58.182Z",
236 | "whenModified": "2021-05-17T01:46:14.309Z"
237 | },
238 | "aprilMayDrummerChanges.opml": {
239 | "ctChars": 15768,
240 | "whenCreated": "2021-05-17T01:39:31.950Z",
241 | "whenModified": "2021-05-17T01:40:20.062Z"
242 | },
243 | "bookmarks.opml": {
244 | "ctChars": 2476,
245 | "whenCreated": "2021-04-23T16:09:01.205Z",
246 | "whenModified": "2021-05-07T15:04:19.598Z"
247 | },
248 | "daveStatus.opml": {
249 | "ctChars": 145031,
250 | "whenCreated": "2021-05-06T14:12:18.230Z",
251 | "whenModified": "2021-05-06T14:14:15.445Z"
252 | },
253 | "dontlooknow.opml": {
254 | "ctChars": 1042,
255 | "whenCreated": "2021-04-23T16:11:49.568Z",
256 | "whenModified": "2021-04-23T16:12:55.524Z"
257 | },
258 | "drummerDocs.opml": {
259 | "ctChars": 5570,
260 | "whenCreated": "2021-05-06T14:16:40.037Z",
261 | "whenModified": "2021-05-17T01:53:08.393Z"
262 | },
263 | "february2021Status.opml": {
264 | "ctChars": 70491,
265 | "whenCreated": "2021-05-17T01:42:57.610Z",
266 | "whenModified": "2021-05-17T01:43:16.802Z"
267 | },
268 | "hello.txt": {
269 | "ctChars": 11,
270 | "whenCreated": "2021-05-29T15:10:36.809Z",
271 | "whenModified": "2021-05-29T16:07:56.474Z"
272 | },
273 | "march2021Status.opml": {
274 | "ctChars": 51300,
275 | "whenCreated": "2021-05-17T01:44:51.166Z",
276 | "whenModified": "2021-05-17T01:45:04.350Z"
277 | },
278 | "menubar.opml": {
279 | "ctChars": 18704,
280 | "whenCreated": "2021-05-06T14:19:03.385Z",
281 | "whenModified": "2021-05-06T14:19:23.521Z"
282 | },
283 | "notes.opml": {
284 | "ctChars": 1855,
285 | "whenCreated": "2021-04-23T16:08:23.549Z",
286 | "whenModified": "2021-05-04T15:01:57.487Z"
287 | },
288 | "opVerbDocs.opml": {
289 | "ctChars": 53897,
290 | "whenCreated": "2021-05-06T14:15:20.717Z",
291 | "whenModified": "2021-05-06T14:15:21.000Z"
292 | },
293 | "opVisitVerbs.opml": {
294 | "ctChars": 3056,
295 | "whenCreated": "2021-05-06T14:25:16.792Z",
296 | "whenModified": "2021-05-06T14:25:17.000Z"
297 | },
298 | "prefs.json": {
299 | "ctChars": 3652,
300 | "whenCreated": "2021-04-23T16:08:24.389Z",
301 | "whenModified": "2021-05-29T16:13:20.017Z"
302 | },
303 | "scheduler.opml": {
304 | "ctChars": 305,
305 | "whenCreated": "2021-05-28T13:53:08.393Z",
306 | "whenModified": "2021-05-28T13:53:08.393Z"
307 | },
308 | "scratchpad.opml": {
309 | "ctChars": 4129,
310 | "whenCreated": "2021-05-06T14:23:30.457Z",
311 | "whenModified": "2021-05-28T18:07:38.836Z"
312 | },
313 | "states.opml": {
314 | "ctChars": 6997,
315 | "whenCreated": "2021-05-06T14:24:16.656Z",
316 | "whenModified": "2021-05-19T20:34:00.863Z"
317 | },
318 | "storage.json": {
319 | "ctChars": 2,
320 | "whenCreated": "2021-04-23T16:08:24.389Z",
321 | "whenModified": "2021-04-23T16:08:24.389Z"
322 | },
323 | "todo.opml": {
324 | "ctChars": 13430,
325 | "whenCreated": "2021-05-06T14:06:02.714Z",
326 | "whenModified": "2021-05-21T16:33:25.355Z"
327 | },
328 | "twitterVerbDocs.opml": {
329 | "ctChars": 21277,
330 | "whenCreated": "2021-05-07T15:02:51.782Z",
331 | "whenModified": "2021-05-07T15:03:06.890Z"
332 | },
333 | "verbDocs.opml": {
334 | "ctChars": 186145,
335 | "whenCreated": "2021-05-06T14:15:21.481Z",
336 | "whenModified": "2021-05-07T15:04:04.578Z"
337 | }
338 | }
339 | }
340 | }
341 |
342 | `console.log (jsonStringify (file.getFileHierarchy ()))`
343 |
344 | - *undefined*
345 |
346 |
--------------------------------------------------------------------------------
/webapp/code.js:
--------------------------------------------------------------------------------
1 | var myVersion = "0.4.4", myProductName = "DocServer";
2 |
3 | var urlDocsOpml = "https://drummer.land/dave.winer@gmail.com/verbDocs.opml";
4 | var docserverOpmltext = undefined;
5 | var docserverOutline = undefined;
6 | var urlUpdateSocket = undefined;
7 | var socketForChanges = undefined;
8 | var verbArray = undefined;
9 | var randomMysteryString; //7/7/21 by DW
10 |
11 | var appPrefs = {
12 | lastVerbViewed: "file.exists",
13 | ixcursor: 0, //index into the verb array
14 | catcursor: 0 //index into categories -- docserverOutline.subs
15 | }
16 | var flPrefsChanged = false;
17 |
18 | function xmlReadFile (url) { //a synchronous file read
19 | var urlReadFileApi = "https://httpproxy.scripting.com/httpReadUrl";
20 | return ($.ajax ({
21 | url: urlReadFileApi + "?url=" + encodeURIComponent (url) + "&type=" + encodeURIComponent ("text/plain"),
22 | headers: {"Accept": "text/x-opml"},
23 | async: false,
24 | dataType: "text" ,
25 | timeout: 30000
26 | }).responseText);
27 | }
28 |
29 | function xmlExpandIncludes (adrx, callback) {
30 | xmlExpandInclude (adrx);
31 | if (xmlHasSubs (adrx)) {
32 | $(adrx).children ("outline").each (function () {
33 | xmlExpandIncludes (this);
34 | });
35 | }
36 | if (callback !== undefined) {
37 | callback ();
38 | }
39 | }
40 | function findInVerbArray (verbName) {
41 | verbName = stringLower (verbName); //unicase search
42 | for (var i = 0; i < verbArray.length; i++) {
43 | var theVerb = verbArray [i];
44 | if (stringLower (theVerb.title) == verbName) {
45 | return (theVerb);
46 | }
47 | }
48 | return (undefined);
49 | }
50 | function redirectToDocserverPage (verbname) { //8/9/21 by DW
51 | var url = stringNthField (stringNthField (window.location.href, "?", 1), "#", 1);
52 | url += "?verb=" + verbname;
53 | window.open (url);
54 | }
55 | function buildVerbsMenu (theOutline, idMenuToInsertAfter) {
56 | var theMenu = $("#idVerbsMenuList");
57 | theMenu.empty ();
58 | theOutline.subs.forEach (function (item, ix) {
59 | var liSubMenuItem = $("" + pgf.text + "
") : $("{
20 | "opml": {
21 | "head": {
22 | "title": "Hello World",
23 | "dateCreated": "Mon, 13 Sep 2021 21:30:28 GMT",
24 | "description": "A simple hello world outline.",
25 | "ownerTwitterScreenName": "cluelessnewbie",
26 | "ownerName": "Clueless Newbie",
27 | "ownerId": "http://twitter.com/cluelessnewbie",
28 | "urlUpdateSocket": "ws://drummer.scripting.com:1232/",
29 | "dateModified": "Mon, 13 Sep 2021 21:37:33 GMT",
30 | "expansionState": "1,2",
31 | "lastCursor": "3"
32 | },
33 | "body": {
34 | "subs": [
35 | {
36 | "text": "A few colors",
37 | "created": "Mon, 13 Sep 2021 21:30:57 GMT",
38 | "subs": [
39 | {
40 | "text": "Blues",
41 | "created": "Mon, 13 Sep 2021 21:31:33 GMT",
42 | "subs": [
43 | {
44 | "text": "Blue green",
45 | "created": "Mon, 13 Sep 2021 21:34:17 GMT"
46 | },
47 | {
48 | "text": "Light blue",
49 | "created": "Mon, 13 Sep 2021 21:34:52 GMT",
50 | "enclosure": "http://mp3.morningcoffeenotes.com/cn18Aug07.mp3",
51 | "enclosureType": "audio/mpeg",
52 | "enclosureLength": "6511738"
53 | },
54 | {
55 | "text": "Sky blue",
56 | "created": "Mon, 13 Sep 2021 21:34:20 GMT"
57 | }
58 | ]
59 | },
60 | {
61 | "text": "Reds",
62 | "created": "Mon, 13 Sep 2021 21:31:35 GMT",
63 | "subs": [
64 | {
65 | "text": "Burnt sienna",
66 | "created": "Mon, 13 Sep 2021 21:34:57 GMT"
67 | },
68 | {
69 | "text": "Cherry",
70 | "created": "Mon, 13 Sep 2021 21:35:23 GMT"
71 | },
72 | {
73 | "text": "Persimmon",
74 | "created": "Mon, 13 Sep 2021 21:35:32 GMT",
75 | "type": "link",
76 | "url": "https://htmlcolorcodes.com/colors/persimmon/"
77 | }
78 | ]
79 | },
80 | {
81 | "text": "Greens",
82 | "created": "Mon, 13 Sep 2021 21:31:37 GMT",
83 | "subs": [
84 | {
85 | "text": "Aqua",
86 | "created": "Mon, 13 Sep 2021 21:31:39 GMT"
87 | },
88 | {
89 | "text": "Cyan ",
90 | "created": "Mon, 13 Sep 2021 21:32:26 GMT"
91 | },
92 | {
93 | "text": "Pistachio",
94 | "created": "Mon, 13 Sep 2021 21:33:55 GMT"
95 | }
96 | ]
97 | }
98 | ]
99 | }
100 | ]
101 | }
102 | }
103 | }
104 |
105 | ## opml.stringify
106 | #### Syntax
107 | opml.stringify (object)
108 |
109 | #### Params
110 | object is a JavaScript object representing an outline.
111 |
112 | #### Returns
113 | The OPML text for the object.
114 |
115 | #### Example
116 | `opml.stringify (opml.parse (file.readWholeFile ("hello.opml")))`
117 |
118 | - *<?xml version="1.0" encoding="ISO-8859-1"?>*
119 |
120 | <opml version="2.0"> 121 | <head> 122 | <title>Hello World</title> 123 | <dateCreated>Mon, 13 Sep 2021 21:30:28 GMT</dateCreated> 124 | <description>A simple hello world outline, with a few subs.</description> 125 | <ownerTwitterScreenName>cluelessnewbie</ownerTwitterScreenName> 126 | <ownerName>Clueless Newbie</ownerName> 127 | <ownerId>http://twitter.com/cluelessnewbie</ownerId> 128 | <urlUpdateSocket>ws://drummer.scripting.com:1232/</urlUpdateSocket> 129 | <dateModified>Mon, 13 Sep 2021 21:37:33 GMT</dateModified> 130 | <expansionState>1,2</expansionState> 131 | <lastCursor>3</lastCursor> 132 | </head> 133 | <body> 134 | <outline text="A few colors" created="Mon, 13 Sep 2021 21:30:57 GMT" > 135 | <outline text="Blues" created="Mon, 13 Sep 2021 21:31:33 GMT" > 136 | <outline text="Blue green" created="Mon, 13 Sep 2021 21:34:17 GMT" /> 137 | <outline text="Light blue" created="Mon, 13 Sep 2021 21:34:52 GMT" enclosure="http://mp3.morningcoffeenotes.com/cn18Aug07.mp3" enclosureType="audio/mpeg" enclosureLength="6511738" /> 138 | <outline text="Sky blue" created="Mon, 13 Sep 2021 21:34:20 GMT" /> 139 | </outline> 140 | <outline text="Reds" created="Mon, 13 Sep 2021 21:31:35 GMT" > 141 | <outline text="Burnt sienna" created="Mon, 13 Sep 2021 21:34:57 GMT" /> 142 | <outline text="Cherry" created="Mon, 13 Sep 2021 21:35:23 GMT" /> 143 | <outline text="Persimmon" created="Mon, 13 Sep 2021 21:35:32 GMT" type="link" url="https://htmlcolorcodes.com/colors/persimmon/" /> 144 | </outline> 145 | <outline text="Greens" created="Mon, 13 Sep 2021 21:31:37 GMT" > 146 | <outline text="Aqua" created="Mon, 13 Sep 2021 21:31:39 GMT" /> 147 | <outline text="Cyan " created="Mon, 13 Sep 2021 21:32:26 GMT" /> 148 | <outline text="Pistachio" created="Mon, 13 Sep 2021 21:33:55 GMT" /> 149 | </outline> 150 | </outline> 151 | </body> 152 | </opml> 153 |154 | ## opml.attributes.addGroup 155 | #### Syntax 156 | opml.attributes.addGroup (string, object) 157 | 158 | #### Params 159 | The string is the name of an OPML file in the user's Drummer account. 160 | 161 | The object is a collection of attributes in the form of a JavaScript object. 162 | 163 | #### What it does 164 | The value of the object replaces is added to the file-level attributes in the OPML file. 165 | 166 | Any previous attributes that are not in the object are not changed, and are still there. 167 | 168 | #### Returns 169 | The attributes of the file after the opml.attributes.setAll call. 170 | 171 | #### Example 172 | `opml.attributes.addGroup ("tmp.opml", {school: "Bronx Science", gpa: 3.5, major: "Art History"})` 173 | 174 |
{
175 | "name": "Bjorn Barker",
176 | "age": "32",
177 | "school": "Bronx Science",
178 | "gpa": 3.5,
179 | "major": "Art History"
180 | }
181 |
182 | ## opml.attributes.deleteOne
183 | #### Syntax
184 | opml.attributes.deleteOne (string, string)
185 |
186 | #### Params
187 | The first string is the name of an OPML file in the user's Drummer account.
188 |
189 | The second string is the name of an attribute.
190 |
191 | #### What it does
192 | Drummer deletes the named attribute in the file, if it exists.
193 |
194 | If the attribute doesn't exist, it is not an error.
195 |
196 | #### Returns
197 | The attributes of the file after the opml.attributes.deleteOne call.
198 |
199 | #### Example
200 | `opml.attributes.deleteOne ("tmp.opml", "height")`
201 |
202 | {
203 | "name": "Bjorn Barker",
204 | "age": "32"
205 | }
206 |
207 | ## opml.attributes.exists
208 | #### Syntax
209 | opml.attributes.exists (string, string)
210 |
211 | #### Params
212 | The first string is the name of an OPML file in the user's Drummer account.
213 |
214 | The second string is the name of an attribute.
215 |
216 | #### Returns
217 | true if the attribute exists in the file, false otherwise.
218 |
219 | #### Examples
220 | `opml.attributes.exists ("tmp.opml", "major")`
221 |
222 | - *true*
223 |
224 | `opml.attributes.exists ("tmp.opml", "minor")`
225 |
226 | - *false*
227 |
228 | ## opml.attributes.getAll
229 | #### Syntax
230 | opml.attributes.getAll (string)
231 |
232 | #### Params
233 | The string is the name of an OPML file in the user's Drummer account.
234 |
235 | #### Returns
236 | All the elements of the <head> section of the OPML file for the outline.
237 |
238 | #### Example
239 | `opml.attributes.getAll ("scratchpad.opml")`
240 |
241 | {
242 | "title": "Scratchpad",
243 | "dateCreated": "Fri, 30 Jul 2021 13:35:09 GMT",
244 | "dateModified": "Mon, 06 Sep 2021 00:26:06 GMT",
245 | "ownerTwitterScreenName": "cluelessnewbie",
246 | "ownerName": "Clueless Newbie",
247 | "ownerId": "http://twitter.com/cluelessnewbie",
248 | "urlUpdateSocket": "ws://drummer.scripting.com:1232/",
249 | "expansionState": "1,2,4,6,15,16,21,23",
250 | "lastCursor": "2"
251 | }
252 |
253 | ## opml.attributes.getOne
254 | #### Syntax
255 | opml.attributes.getOne (string, string)
256 |
257 | #### Params
258 | The first string is the name of an OPML file in the user's Drummer account.
259 |
260 | The second string is the name of an attribute.
261 |
262 | #### Returns
263 | The value of the named attribute.
264 |
265 | If the attribute doesn't exist, the value returned is the JavaScript value undefined.
266 |
267 | #### Example
268 | `opml.attributes.getOne ("tmp.opml", "name")`
269 |
270 | - *Bjorn Barker*
271 |
272 | `opml.attributes.getOne ("tmp.opml", "hometown")`
273 |
274 | - *undefined*
275 |
276 | ## opml.attributes.makeEmpty
277 | #### Syntax
278 | opml.attributes.makeEmpty (string)
279 |
280 | #### Params
281 | The first string is the name of an OPML file in the user's Drummer account.
282 |
283 | #### What it does
284 | Drummer deletes all the named attributes in the file.
285 |
286 | #### Returns
287 | The attributes of the file after the opml.attributes.deleteOne call.
288 |
289 | #### Example
290 | `opml.attributes.makeEmpty ("tmp.opml")`
291 |
292 | - *{ }*
293 |
294 | ## opml.attributes.setAll
295 | #### Syntax
296 | opml.attributes.setAll (string, object)
297 |
298 | #### Params
299 | The string is the name of an OPML file in the user's Drummer account.
300 |
301 | The object is a collection of attributes in the form of a JavaScript object.
302 |
303 | #### What it does
304 | The value of the object replaces all file-level attributes in the OPML file.
305 |
306 | The object should contain only name-value pairs.
307 |
308 | #### Returns
309 | The attributes of the file after the opml.attributes.setAll call.
310 |
311 | #### Example
312 | `opml.attributes.setAll ("tmp.opml", {name: "Bjorn Barker", age: 32})`
313 |
314 | - *true*
315 |
316 | ## opml.attributes.setOne
317 | #### Syntax
318 | opml.attributes.setOne (string, string, value)
319 |
320 | #### Params
321 | The first string is the name of an OPML file in the user's Drummer account.
322 |
323 | The second string is the name of an attribute.
324 |
325 | value is a JavaScript string, or a value that can be coerced to a string.
326 |
327 | #### What it does
328 | Drummer sets the value of the named attribute in the file.
329 |
330 | The attribute might exist, in which case its value is overwritten, or it is created.
331 |
332 | #### Returns
333 | The attributes of the file after the opml.attributes.setOne call.
334 |
335 | #### Example
336 | `opml.attributes.setOne ("tmp.opml", "height", 5.5 * 12)`
337 |
338 | {
339 | "name": "Bjorn Barker",
340 | "age": "32",
341 | "height": 66
342 | }
343 |
344 | ## opml.getCurrentObject
345 | #### Syntax
346 | opml.getCurrentObject ()
347 |
348 | #### Params
349 | None.
350 |
351 | #### Returns
352 | A JavaScript object with all the data contained in the current outline, accessible directly in JavaScript code.
353 |
354 | #### Note
355 | It does what opml.getCurrentOpml does, except instead of returning OPML text, it returns the same information as a JavaScript object.
356 |
357 | #### Example
358 | `opml.getCurrentObject ()`
359 |
360 | {
361 | "head": {
362 | "title": "test",
363 | "dateCreated": "Wed, 07 Apr 2021 16:05:20 GMT",
364 | "dateModified": "Wed, 07 Apr 2021 16:17:01 GMT"
365 | },
366 | "body": {
367 | "subs": [
368 | {
369 | "text": "Hello World",
370 | "created": "Wed, 07 Apr 2021 15:53:15 GMT"
371 | }
372 | ]
373 | }
374 | }
375 |
376 | ## opml.getCurrentOpml
377 | #### Syntax
378 | opml.getCurrentOpml ()
379 |
380 | #### Params
381 | None.
382 |
383 | #### Returns
384 | The text returned is exactly what would be saved as OPML for the current outline.
385 |
386 | #### Example
387 | `opml.getCurrentOpml ()`
388 |
389 | - *<?xml version="1.0"?>*
390 |
391 | <opml version="2.0"> 392 | <head> 393 | <title>A menu for meals</title> 394 | <dateCreated>Sat, 11 Sep 2021 14:40:49 GMT</dateCreated> 395 | <dateModified>Tue, 16 Nov 2021 21:20:48 GMT</dateModified> 396 | </head> 397 | <body> 398 | <outline text="Hello World" created="Tue, 16 Nov 2021 21:18:13 GMT"> 399 | </outline> 400 | </body> 401 | </opml> 402 |403 | ## opml.getMarkdown 404 | #### Syntax 405 | opml.getMarkdown (opmltext) 406 | 407 | #### Params 408 | opmltext is a string containing text in OPML format. 409 | 410 | #### Returns 411 | The markdown-from-outline algorithm that was implemented in Old School. 412 | 413 | #### Notes 414 | This is markdown text for publishing, not for interop with outliners. 415 | 416 | We add two newlines at the end of the text of every outline node. 417 | 418 | We generate nothing for indentation, you can use that in your writing in any way that suits you. 419 | 420 | We respect the flSinglespaceMarkdown attribute. When it's present and true, we only add one newline for the subs. We also generate an extra newline at the end of the subs. 421 | 422 | #### Example 423 | `Here's the example outline:` 424 | 425 |
Foods I like 426 | Cheese 427 | Bagels 428 | Everything 429 | Sesame 430 | Plain 431 | Sauces 432 |433 | `Bagels has a flSinglespaceMarkdown attribute with the value true.` 434 | 435 | `We ran this script.` 436 | 437 | - *console.log (opml.getMarkdown (op.getCursorOpml (false)))* 438 | 439 | `Which generated this text.` 440 | 441 | - *Cheese* 442 | 443 | - *
[
104 | {
105 | "name": "README.md",
106 | "path": "README.md",
107 | "sha": "449f080ed3d5eca1c16edfc0d14ed0851ee51a05",
108 | "size": 30,
109 | "url": "https://api.github.com/repos/scripting/tmp1/contents/README.md?ref=main",
110 | "html_url": "https://github.com/scripting/tmp1/blob/main/README.md",
111 | "git_url": "https://api.github.com/repos/scripting/tmp1/git/blobs/449f080ed3d5eca1c16edfc0d14ed0851ee51a05",
112 | "download_url": "https://raw.githubusercontent.com/scripting/tmp1/main/README.md",
113 | "type": "file",
114 | "_links": {
115 | "self": "https://api.github.com/repos/scripting/tmp1/contents/README.md?ref=main",
116 | "git": "https://api.github.com/repos/scripting/tmp1/git/blobs/449f080ed3d5eca1c16edfc0d14ed0851ee51a05",
117 | "html": "https://github.com/scripting/tmp1/blob/main/README.md"
118 | }
119 | },
120 | {
121 | "name": "andSheWas.opml",
122 | "path": "andSheWas.opml",
123 | "sha": "8197f7b204207b55b4e26fc292fe1b974c73406d",
124 | "size": 3233,
125 | "url": "https://api.github.com/repos/scripting/tmp1/contents/andSheWas.opml?ref=main",
126 | "html_url": "https://github.com/scripting/tmp1/blob/main/andSheWas.opml",
127 | "git_url": "https://api.github.com/repos/scripting/tmp1/git/blobs/8197f7b204207b55b4e26fc292fe1b974c73406d",
128 | "download_url": "https://raw.githubusercontent.com/scripting/tmp1/main/andSheWas.opml",
129 | "type": "file",
130 | "_links": {
131 | "self": "https://api.github.com/repos/scripting/tmp1/contents/andSheWas.opml?ref=main",
132 | "git": "https://api.github.com/repos/scripting/tmp1/git/blobs/8197f7b204207b55b4e26fc292fe1b974c73406d",
133 | "html": "https://github.com/scripting/tmp1/blob/main/andSheWas.opml"
134 | }
135 | },
136 | {
137 | "name": "buzz.md",
138 | "path": "buzz.md",
139 | "sha": "9f65b87f16ca67b8033b028be0c0bab35da5bd8f",
140 | "size": 30,
141 | "url": "https://api.github.com/repos/scripting/tmp1/contents/buzz.md?ref=main",
142 | "html_url": "https://github.com/scripting/tmp1/blob/main/buzz.md",
143 | "git_url": "https://api.github.com/repos/scripting/tmp1/git/blobs/9f65b87f16ca67b8033b028be0c0bab35da5bd8f",
144 | "download_url": "https://raw.githubusercontent.com/scripting/tmp1/main/buzz.md",
145 | "type": "file",
146 | "_links": {
147 | "self": "https://api.github.com/repos/scripting/tmp1/contents/buzz.md?ref=main",
148 | "git": "https://api.github.com/repos/scripting/tmp1/git/blobs/9f65b87f16ca67b8033b028be0c0bab35da5bd8f",
149 | "html": "https://github.com/scripting/tmp1/blob/main/buzz.md"
150 | }
151 | },
152 | {
153 | "name": "buzz.txt",
154 | "path": "buzz.txt",
155 | "sha": "b89a0f4ed3bc9334e0e39ccfeae06aebf3c213b9",
156 | "size": 26,
157 | "url": "https://api.github.com/repos/scripting/tmp1/contents/buzz.txt?ref=main",
158 | "html_url": "https://github.com/scripting/tmp1/blob/main/buzz.txt",
159 | "git_url": "https://api.github.com/repos/scripting/tmp1/git/blobs/b89a0f4ed3bc9334e0e39ccfeae06aebf3c213b9",
160 | "download_url": "https://raw.githubusercontent.com/scripting/tmp1/main/buzz.txt",
161 | "type": "file",
162 | "_links": {
163 | "self": "https://api.github.com/repos/scripting/tmp1/contents/buzz.txt?ref=main",
164 | "git": "https://api.github.com/repos/scripting/tmp1/git/blobs/b89a0f4ed3bc9334e0e39ccfeae06aebf3c213b9",
165 | "html": "https://github.com/scripting/tmp1/blob/main/buzz.txt"
166 | }
167 | },
168 | {
169 | "name": "menubar.opml",
170 | "path": "menubar.opml",
171 | "sha": "18f8da4953d764729d0250479435e61b83d4b972",
172 | "size": 1950,
173 | "url": "https://api.github.com/repos/scripting/tmp1/contents/menubar.opml?ref=main",
174 | "html_url": "https://github.com/scripting/tmp1/blob/main/menubar.opml",
175 | "git_url": "https://api.github.com/repos/scripting/tmp1/git/blobs/18f8da4953d764729d0250479435e61b83d4b972",
176 | "download_url": "https://raw.githubusercontent.com/scripting/tmp1/main/menubar.opml",
177 | "type": "file",
178 | "_links": {
179 | "self": "https://api.github.com/repos/scripting/tmp1/contents/menubar.opml?ref=main",
180 | "git": "https://api.github.com/repos/scripting/tmp1/git/blobs/18f8da4953d764729d0250479435e61b83d4b972",
181 | "html": "https://github.com/scripting/tmp1/blob/main/menubar.opml"
182 | }
183 | }
184 | ]
185 |
186 | `github.getDirectory ("scripting", "Scripting-News", "/blog/opml/2017")`
187 |
188 | [
189 | {
190 | "name": "05.opml",
191 | "path": "blog/opml/2017/05.opml",
192 | "sha": "69cd335c1d713c37e136fc97b875072a24c92ea3",
193 | "size": 117772,
194 | "url": "https://api.github.com/repos/scripting/Scripting-News/contents/blog/opml/2017/05.opml?ref=master",
195 | "html_url": "https://github.com/scripting/Scripting-News/blob/master/blog/opml/2017/05.opml",
196 | "git_url": "https://api.github.com/repos/scripting/Scripting-News/git/blobs/69cd335c1d713c37e136fc97b875072a24c92ea3",
197 | "download_url": "https://raw.githubusercontent.com/scripting/Scripting-News/master/blog/opml/2017/05.opml",
198 | "type": "file",
199 | "_links": {
200 | "self": "https://api.github.com/repos/scripting/Scripting-News/contents/blog/opml/2017/05.opml?ref=master",
201 | "git": "https://api.github.com/repos/scripting/Scripting-News/git/blobs/69cd335c1d713c37e136fc97b875072a24c92ea3",
202 | "html": "https://github.com/scripting/Scripting-News/blob/master/blog/opml/2017/05.opml"
203 | }
204 | },
205 | {
206 | "name": "06.opml",
207 | "path": "blog/opml/2017/06.opml",
208 | "sha": "864439149998198cbebbd142b24d1d4cd71196f5",
209 | "size": 209566,
210 | "url": "https://api.github.com/repos/scripting/Scripting-News/contents/blog/opml/2017/06.opml?ref=master",
211 | "html_url": "https://github.com/scripting/Scripting-News/blob/master/blog/opml/2017/06.opml",
212 | "git_url": "https://api.github.com/repos/scripting/Scripting-News/git/blobs/864439149998198cbebbd142b24d1d4cd71196f5",
213 | "download_url": "https://raw.githubusercontent.com/scripting/Scripting-News/master/blog/opml/2017/06.opml",
214 | "type": "file",
215 | "_links": {
216 | "self": "https://api.github.com/repos/scripting/Scripting-News/contents/blog/opml/2017/06.opml?ref=master",
217 | "git": "https://api.github.com/repos/scripting/Scripting-News/git/blobs/864439149998198cbebbd142b24d1d4cd71196f5",
218 | "html": "https://github.com/scripting/Scripting-News/blob/master/blog/opml/2017/06.opml"
219 | }
220 | },
221 | {
222 | "name": "08.opml",
223 | "path": "blog/opml/2017/08.opml",
224 | "sha": "838e15184ae527659fd3273f89f3419a0f283ecd",
225 | "size": 134679,
226 | "url": "https://api.github.com/repos/scripting/Scripting-News/contents/blog/opml/2017/08.opml?ref=master",
227 | "html_url": "https://github.com/scripting/Scripting-News/blob/master/blog/opml/2017/08.opml",
228 | "git_url": "https://api.github.com/repos/scripting/Scripting-News/git/blobs/838e15184ae527659fd3273f89f3419a0f283ecd",
229 | "download_url": "https://raw.githubusercontent.com/scripting/Scripting-News/master/blog/opml/2017/08.opml",
230 | "type": "file",
231 | "_links": {
232 | "self": "https://api.github.com/repos/scripting/Scripting-News/contents/blog/opml/2017/08.opml?ref=master",
233 | "git": "https://api.github.com/repos/scripting/Scripting-News/git/blobs/838e15184ae527659fd3273f89f3419a0f283ecd",
234 | "html": "https://github.com/scripting/Scripting-News/blob/master/blog/opml/2017/08.opml"
235 | }
236 | },
237 | {
238 | "name": "09.opml",
239 | "path": "blog/opml/2017/09.opml",
240 | "sha": "f7c49b9358350b1174ee3199821ceab771618551",
241 | "size": 149136,
242 | "url": "https://api.github.com/repos/scripting/Scripting-News/contents/blog/opml/2017/09.opml?ref=master",
243 | "html_url": "https://github.com/scripting/Scripting-News/blob/master/blog/opml/2017/09.opml",
244 | "git_url": "https://api.github.com/repos/scripting/Scripting-News/git/blobs/f7c49b9358350b1174ee3199821ceab771618551",
245 | "download_url": "https://raw.githubusercontent.com/scripting/Scripting-News/master/blog/opml/2017/09.opml",
246 | "type": "file",
247 | "_links": {
248 | "self": "https://api.github.com/repos/scripting/Scripting-News/contents/blog/opml/2017/09.opml?ref=master",
249 | "git": "https://api.github.com/repos/scripting/Scripting-News/git/blobs/f7c49b9358350b1174ee3199821ceab771618551",
250 | "html": "https://github.com/scripting/Scripting-News/blob/master/blog/opml/2017/09.opml"
251 | }
252 | },
253 | {
254 | "name": "10.opml",
255 | "path": "blog/opml/2017/10.opml",
256 | "sha": "f05dd3581a93f26d8e972cecffb0c313e480e873",
257 | "size": 120405,
258 | "url": "https://api.github.com/repos/scripting/Scripting-News/contents/blog/opml/2017/10.opml?ref=master",
259 | "html_url": "https://github.com/scripting/Scripting-News/blob/master/blog/opml/2017/10.opml",
260 | "git_url": "https://api.github.com/repos/scripting/Scripting-News/git/blobs/f05dd3581a93f26d8e972cecffb0c313e480e873",
261 | "download_url": "https://raw.githubusercontent.com/scripting/Scripting-News/master/blog/opml/2017/10.opml",
262 | "type": "file",
263 | "_links": {
264 | "self": "https://api.github.com/repos/scripting/Scripting-News/contents/blog/opml/2017/10.opml?ref=master",
265 | "git": "https://api.github.com/repos/scripting/Scripting-News/git/blobs/f05dd3581a93f26d8e972cecffb0c313e480e873",
266 | "html": "https://github.com/scripting/Scripting-News/blob/master/blog/opml/2017/10.opml"
267 | }
268 | },
269 | {
270 | "name": "11.opml",
271 | "path": "blog/opml/2017/11.opml",
272 | "sha": "f06576fac10c3aedbf24a322df4df52ad046b9e9",
273 | "size": 114018,
274 | "url": "https://api.github.com/repos/scripting/Scripting-News/contents/blog/opml/2017/11.opml?ref=master",
275 | "html_url": "https://github.com/scripting/Scripting-News/blob/master/blog/opml/2017/11.opml",
276 | "git_url": "https://api.github.com/repos/scripting/Scripting-News/git/blobs/f06576fac10c3aedbf24a322df4df52ad046b9e9",
277 | "download_url": "https://raw.githubusercontent.com/scripting/Scripting-News/master/blog/opml/2017/11.opml",
278 | "type": "file",
279 | "_links": {
280 | "self": "https://api.github.com/repos/scripting/Scripting-News/contents/blog/opml/2017/11.opml?ref=master",
281 | "git": "https://api.github.com/repos/scripting/Scripting-News/git/blobs/f06576fac10c3aedbf24a322df4df52ad046b9e9",
282 | "html": "https://github.com/scripting/Scripting-News/blob/master/blog/opml/2017/11.opml"
283 | }
284 | },
285 | {
286 | "name": "12.opml",
287 | "path": "blog/opml/2017/12.opml",
288 | "sha": "a016cfe0146629d8f2b85003f9cf36e23ba43415",
289 | "size": 129193,
290 | "url": "https://api.github.com/repos/scripting/Scripting-News/contents/blog/opml/2017/12.opml?ref=master",
291 | "html_url": "https://github.com/scripting/Scripting-News/blob/master/blog/opml/2017/12.opml",
292 | "git_url": "https://api.github.com/repos/scripting/Scripting-News/git/blobs/a016cfe0146629d8f2b85003f9cf36e23ba43415",
293 | "download_url": "https://raw.githubusercontent.com/scripting/Scripting-News/master/blog/opml/2017/12.opml",
294 | "type": "file",
295 | "_links": {
296 | "self": "https://api.github.com/repos/scripting/Scripting-News/contents/blog/opml/2017/12.opml?ref=master",
297 | "git": "https://api.github.com/repos/scripting/Scripting-News/git/blobs/a016cfe0146629d8f2b85003f9cf36e23ba43415",
298 | "html": "https://github.com/scripting/Scripting-News/blob/master/blog/opml/2017/12.opml"
299 | }
300 | }
301 | ]
302 |
303 | ## github.getUserInfo
304 | #### Syntax
305 | github.getUserInfo (string)
306 |
307 | #### Params
308 | The string, which is optional, is the username of the account you want the information of.
309 |
310 | #### Returns
311 | If the username is not provided, github.getUserInfo returns a JavaScript object containing the user info for the current logged-in user.
312 |
313 | #### Examples
314 | `github.getUserInfo ()`
315 |
316 | {
317 | "login": "scripting",
318 | "id": 1686843,
319 | "node_id": "MDQ6VXNlcjE2ODY4NDM=",
320 | "avatar_url": "https://avatars.githubusercontent.com/u/1686843?v=4",
321 | "gravatar_id": "",
322 | "url": "https://api.github.com/users/scripting",
323 | "html_url": "https://github.com/scripting",
324 | "followers_url": "https://api.github.com/users/scripting/followers",
325 | "following_url": "https://api.github.com/users/scripting/following{/other_user }",
326 | "gists_url": "https://api.github.com/users/scripting/gists{/gist_id }",
327 | "starred_url": "https://api.github.com/users/scripting/starred{/owner }{/repo }",
328 | "subscriptions_url": "https://api.github.com/users/scripting/subscriptions",
329 | "organizations_url": "https://api.github.com/users/scripting/orgs",
330 | "repos_url": "https://api.github.com/users/scripting/repos",
331 | "events_url": "https://api.github.com/users/scripting/events{/privacy }",
332 | "received_events_url": "https://api.github.com/users/scripting/received_events",
333 | "type": "User",
334 | "site_admin": false,
335 | "name": "Dave Winer",
336 | "company": "Small Picture, Inc.",
337 | "blog": "http://davewiner.com/",
338 | "location": "Woodstock, NY",
339 | "email": "dave.winer@gmail.com",
340 | "hireable": null,
341 | "bio": "On the net since mid-70s. Started two Silicon Valley companies. Wrote for Wired. Fellow at Harvard, NYU. Founder of podcasting, blogging, RSS. Open web.",
342 | "twitter_username": null,
343 | "public_repos": 130,
344 | "public_gists": 159,
345 | "followers": 704,
346 | "following": 49,
347 | "created_at": "2012-04-28T01:19:35Z",
348 | "updated_at": "2021-08-03T13:52:51Z"
349 | }
350 |
351 | `github.getUserInfo ("octocat")`
352 |
353 | {
354 | "login": "octocat",
355 | "id": 583231,
356 | "node_id": "MDQ6VXNlcjU4MzIzMQ==",
357 | "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4",
358 | "gravatar_id": "",
359 | "url": "https://api.github.com/users/octocat",
360 | "html_url": "https://github.com/octocat",
361 | "followers_url": "https://api.github.com/users/octocat/followers",
362 | "following_url": "https://api.github.com/users/octocat/following{/other_user }",
363 | "gists_url": "https://api.github.com/users/octocat/gists{/gist_id }",
364 | "starred_url": "https://api.github.com/users/octocat/starred{/owner }{/repo }",
365 | "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
366 | "organizations_url": "https://api.github.com/users/octocat/orgs",
367 | "repos_url": "https://api.github.com/users/octocat/repos",
368 | "events_url": "https://api.github.com/users/octocat/events{/privacy }",
369 | "received_events_url": "https://api.github.com/users/octocat/received_events",
370 | "type": "User",
371 | "site_admin": false,
372 | "name": "The Octocat",
373 | "company": "@github",
374 | "blog": "https://github.blog",
375 | "location": "San Francisco",
376 | "email": "octocat@github.com",
377 | "hireable": null,
378 | "bio": null,
379 | "twitter_username": null,
380 | "public_repos": 8,
381 | "public_gists": 8,
382 | "followers": 4147,
383 | "following": 9,
384 | "created_at": "2011-01-25T18:44:36Z",
385 | "updated_at": "2021-10-22T14:27:39Z"
386 | }
387 |
388 | ## github.upload
389 | #### Syntax
390 | github.upload (username, repository, path, data, message)
391 |
392 | #### Params
393 | The first two strings identify a GitHub repository. The first is the username, and the second is the name of the repository in the user's GitHub account.
394 |
395 | The third string is a path to the object you want to upload.
396 |
397 | The fourth string is the data of the file to be created by the upload.
398 |
399 | The fifth string is the "commit message" that is displayed next to the object in GitHub. It it is not supplied, the server generates a random slogan for the commit message.
400 |
401 | #### Returns
402 | All the information GitHub returns about the upload.
403 |
404 | #### Examples
405 | `github.upload ("scripting", "tmp1", "hello.txt", "Hello World")`
406 |
407 | {
408 | "content": {
409 | "name": "hello.txt",
410 | "path": "hello.txt",
411 | "sha": "5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689",
412 | "size": 11,
413 | "url": "https://api.github.com/repos/scripting/tmp1/contents/hello.txt?ref=main",
414 | "html_url": "https://github.com/scripting/tmp1/blob/main/hello.txt",
415 | "git_url": "https://api.github.com/repos/scripting/tmp1/git/blobs/5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689",
416 | "download_url": "https://raw.githubusercontent.com/scripting/tmp1/main/hello.txt",
417 | "type": "file",
418 | "_links": {
419 | "self": "https://api.github.com/repos/scripting/tmp1/contents/hello.txt?ref=main",
420 | "git": "https://api.github.com/repos/scripting/tmp1/git/blobs/5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689",
421 | "html": "https://github.com/scripting/tmp1/blob/main/hello.txt"
422 | }
423 | },
424 | "commit": {
425 | "sha": "e0ef91110335af449223826acdc681988e441aad",
426 | "node_id": "C_kwDOGWnhedoAKGUwZWY5MTExMDMzNWFmNDQ5MjIzODI2YWNkYzY4MTk4OGU0NDFhYWQ",
427 | "url": "https://api.github.com/repos/scripting/tmp1/git/commits/e0ef91110335af449223826acdc681988e441aad",
428 | "html_url": "https://github.com/scripting/tmp1/commit/e0ef91110335af449223826acdc681988e441aad",
429 | "author": {
430 | "name": "Dave Winer",
431 | "email": "dave.winer@gmail.com",
432 | "date": "2021-11-10T20:52:18Z"
433 | },
434 | "committer": {
435 | "name": "Dave Winer",
436 | "email": "dave.winer@gmail.com",
437 | "date": "2021-11-10T20:52:18Z"
438 | },
439 | "tree": {
440 | "sha": "d225f272b14b41078d954bd7d7d75f85c876a66b",
441 | "url": "https://api.github.com/repos/scripting/tmp1/git/trees/d225f272b14b41078d954bd7d7d75f85c876a66b"
442 | },
443 | "message": "Takes a lickin, keeps on tickin.",
444 | "parents": [
445 | {
446 | "sha": "7a6ac66cd728566fbe9bd10bc38882e6ff1f060a",
447 | "url": "https://api.github.com/repos/scripting/tmp1/git/commits/7a6ac66cd728566fbe9bd10bc38882e6ff1f060a",
448 | "html_url": "https://github.com/scripting/tmp1/commit/7a6ac66cd728566fbe9bd10bc38882e6ff1f060a"
449 | }
450 | ],
451 | "verification": {
452 | "verified": false,
453 | "reason": "unsigned",
454 | "signature": null,
455 | "payload": null
456 | }
457 | },
458 | "statusCode": 201
459 | }
460 |
461 |
--------------------------------------------------------------------------------
/docs/pages/op.md:
--------------------------------------------------------------------------------
1 |
2 | # op verbs
3 | ## op.attributes.addGroup
4 | #### Syntax
5 | op.attributes.addGroup (object)
6 |
7 | #### Params
8 | The properties of the object parameter are added to the bar cursor headline.
9 |
10 | #### Returns
11 | The object.
12 |
13 | #### Example
14 | `op.attributes.addGroup ({age: 98, hair: "brown", location: "Minnesota"})`
15 |
16 | {
17 | "age": 98,
18 | "hair": "brown",
19 | "location": "Minnesota"
20 | }
21 |
22 | ## op.attributes.deleteOne
23 | #### Syntax
24 | op.attributes.deleteOne (name)
25 |
26 | #### Params
27 | The string is the name of an attribute.
28 |
29 | #### What it does
30 | The attribute is deleted on the bar cursor headline, if it exists.
31 |
32 | #### Returns
33 | true if it deleted the att, false if it didn't.
34 |
35 | #### Example
36 | `op.attributes.deleteOne ("age")`
37 |
38 | - *false*
39 |
40 | `op.attributes.deleteOne ("location")`
41 |
42 | - *true*
43 |
44 | ## op.attributes.exists
45 | #### Syntax
46 | op.attributes.exists (string)
47 |
48 | #### Params
49 | The string is the name of an attribute.
50 |
51 | #### Returns
52 | If the attribute exists on the bar cursor headline it returns true, false otherwise.
53 |
54 | #### Example
55 | `op.attributes.exists ("created")`
56 |
57 | - *true*
58 |
59 | `op.attributes.exists ("mysteryAttribute")`
60 |
61 | - *false*
62 |
63 | ## op.attributes.getAll
64 | #### Syntax
65 | op.attributes.getAll ()
66 |
67 | #### Params
68 | None.
69 |
70 | #### Returns
71 | A JavaScript object containing all the attributes attached to the bar cursor headline.
72 |
73 | #### Example
74 | `op.attributes.getAll ()`
75 |
76 | {
77 | "created": "Tue, 30 Mar 2021 16:07:59 GMT",
78 | "age": "32"
79 | }
80 |
81 | ## op.attributes.getOne
82 | #### Syntax
83 | op.attributes.getOne (string)
84 |
85 | #### Params
86 | The string is the name of an attribute.
87 |
88 | #### Returns
89 | The value of the named attribute on the bar cursor headline.
90 |
91 | If the attribute doesn't exist, it returns undefined.
92 |
93 | #### Example
94 | `op.attributes.getOne ("created")`
95 |
96 | - *Tue, 30 Mar 2021 16:07:59 GMT*
97 |
98 | `op.attributes.getOne ("meaningOfLife")`
99 |
100 | - *undefined*
101 |
102 | ## op.attributes.makeEmpty
103 | #### Syntax
104 | op.attributes.makeEmpty ()
105 |
106 | #### Params
107 | None.
108 |
109 | #### What it does
110 | Removes all the attributes of the bar cursor headline.
111 |
112 | #### Bug
113 | When we remove the created attribute, it is replaced automatically. Not clear where this is happening, but it probably shouldn't be doing this.
114 |
115 | #### Returns
116 | true.
117 |
118 | #### Example
119 | `op.attributes.makeEmpty ()`
120 |
121 | - *true*
122 |
123 | ## op.attributes.setOne
124 | #### Syntax
125 | op.attributes.setOne (name, val)
126 |
127 | #### Params
128 | Both params are strings.
129 |
130 | The first is the name of the attribute of the bar cursor headline that you want to set.
131 |
132 | The second is the value that will be assigned to the attribute.
133 |
134 | #### Returns
135 | true.
136 |
137 | #### Example
138 | `op.attributes.setOne ("age", random (1, 99))`
139 |
140 | - *true*
141 |
142 | ## op.bold
143 | #### Syntax
144 | op.bold ()
145 |
146 | #### Params
147 | None.
148 |
149 | #### What it does
150 | The selected text in the bar cursor headline is boldened.
151 |
152 | #### Notes
153 | The text is boldened by wrapping it in an HTML <b> element.
154 |
155 | #### Returns
156 | undefined.
157 |
158 | #### Example
159 | `op.bold ()`
160 |
161 | - *undefined*
162 |
163 | ## op.collapseEverything
164 | #### Syntax
165 | op.collapseEverything ()
166 |
167 | #### Params
168 | None.
169 |
170 | #### What it does
171 | Collapses everything in the outline and moves the bar cursor to the first summit.
172 |
173 | #### Returns
174 | The value undefined.
175 |
176 | #### Bug
177 | The bar cursor does not go to the first summit, there is no cursor after this runs.
178 |
179 | #### Example
180 | `op.collapseEverything ()`
181 |
182 | - *undefined*
183 |
184 | ## op.collapse
185 | #### Syntax
186 | op.collapse ()
187 |
188 | #### Params
189 | None.
190 |
191 | #### What it does
192 | Collapses the bar cursor headline making all its children not visible.
193 |
194 | #### Returns
195 | The value undefined.
196 |
197 | #### Example
198 | `op.collapse ()`
199 |
200 | - *undefined*
201 |
202 | ## op.countSubs
203 | #### Syntax
204 | op.countSubs ()
205 |
206 | #### Params
207 | None.
208 |
209 | #### Returns
210 | The number of children the bar cursor headline has.
211 |
212 | #### Example
213 | `op.countSubs ()`
214 |
215 | - *1*
216 |
217 | ## op.deleteSubs
218 | #### Syntax
219 | op.deleteSubs ()
220 |
221 | #### Params
222 | None.
223 |
224 | #### What it does
225 | Deletes all the children of the bar cursor headline.
226 |
227 | #### Returns
228 | undefined.
229 |
230 | #### Examples
231 | `op.deleteSubs ()`
232 |
233 | - *undefined*
234 |
235 | ## op.demote
236 | #### Syntax
237 | op.demote ()
238 |
239 | #### Params
240 | None.
241 |
242 | #### What it does
243 | All siblings down from the bar cursor headline are moved to the right, to become children of the bar cursor headline.
244 |
245 | The bar cursor headline is expanded if necessary.
246 |
247 | #### Returns
248 | undefined.
249 |
250 | #### Examples
251 | `op.demote ()`
252 |
253 | - *undefined*
254 |
255 | ## op.expandAllLevels
256 | #### Syntax
257 | op.expandAllLevels ()
258 |
259 | #### Params
260 | None.
261 |
262 | #### What it does
263 | Expands the bar cursor headline making all its children, and all their descendants, visible.
264 |
265 | #### Returns
266 | The value undefined.
267 |
268 | #### Example
269 | `op.expandAllLevels ()`
270 |
271 | - *undefined*
272 |
273 | ## op.expand
274 | #### Syntax
275 | op.expand ()
276 |
277 | #### Params
278 | None.
279 |
280 | #### What it does
281 | Expands the bar cursor headline making all its children visible.
282 |
283 | #### Returns
284 | The value undefined.
285 |
286 | #### Notes
287 | The Frontier version of this verb takes a number param, that determines the number of levels to be expanded.
288 |
289 | #### Example
290 | `op.expand ()`
291 |
292 | - *undefined*
293 |
294 | ## op.expandTo
295 | #### Syntax
296 | op.expandTo (
297 |
298 | ## op.firstSummit
299 | #### Syntax
300 | op.firstSummit ()
301 |
302 | #### Params
303 | None.
304 |
305 | #### Returns
306 | undefined.
307 |
308 | #### Bug
309 | It does not return undefined, it returns true.
310 |
311 | #### Example
312 | `op.firstSummit ()`
313 |
314 | - *true*
315 |
316 | ## op.getCursorJstruct
317 | #### Syntax
318 | op.getCursorJstruct ()
319 |
320 | #### Params
321 | None.
322 |
323 | #### Returns
324 | A JavaScript object representing all the data in the outline subordinate to the bar cursor headline.
325 |
326 | This is useful if you want to process the text under the bar cursor headline by traversing a JavaScript object.
327 |
328 | #### Example
329 | `op.getCursorJstruct ()`
330 |
331 | {
332 | "created": "Tue, 16 Nov 2021 14:55:40 GMT",
333 | "text": "Hello World"
334 | }
335 |
336 | ## op.getCursorOpml
337 | #### Syntax
338 | op.getCursorOpml (flSubsOnly)
339 |
340 | #### Params
341 | The boolean parameter is optional. If true, we return the OPML text for the subs only, otherwise we include the bar cursor headline.
342 |
343 | If it's not specified it defaults to false.
344 |
345 | #### Returns
346 | A string containing the OPML text of the bar cursor headline and all its subs, if flSubsOnly is false. If flSubsOnly is true, it returns the OPML text for the subs.
347 |
348 | #### Note
349 | The title in the <head> section of the OPML is set to the text of the bar cursor headline, so even if flSubsOnly is true, the text of the bar cursor headline is still included in the OPML.
350 |
351 | The optional boolean was added on 11/28/2021 to provide a way to get just the subs, but the default behavior was as it was before, so as not to break any existing scripts.
352 |
353 | #### Examples
354 | `op.getCursorOpml (true)`
355 |
356 | - *<?xml version="1.0"?>*
357 |
358 | <opml version="2.0"> 359 | <head> 360 | <title>Foods I like</title> 361 | </head> 362 | <body> 363 | <outline text="Lettuce"/> 364 | <outline text="Beans"> 365 | <outline text="String"/> 366 | <outline text="Baked" created="Sun, 28 Nov 2021 14:43:14 GMT"/> 367 | </outline> 368 | <outline text="Cake"/> 369 | </body> 370 | </opml> 371 |372 | `op.getCursorOpml (false)` 373 | 374 | - *<?xml version="1.0"?>* 375 | 376 |
<opml version="2.0"> 377 | <head> 378 | <title>Foods I like</title> 379 | </head> 380 | <body> 381 | <outline text="Foods I like" type="outline"> 382 | <outline text="Lettuce"/> 383 | <outline text="Beans"> 384 | <outline text="String"/> 385 | <outline text="Baked"/> 386 | </outline> 387 | <outline text="Cake"/> 388 | </outline> 389 | </body> 390 | </opml> 391 |392 | ## op.getCursor 393 | #### Syntax 394 | op.getCursor () 395 | 396 | #### Params 397 | None. 398 | 399 | #### Bug 400 | There does not appear to be an op.setCursor to balance this verb. 401 | 402 | #### Returns 403 | An object representing the bar cursor. 404 | 405 | #### Example 406 | `op.getCursor ()` 407 | 408 | - *{ "attributes": { "_cssTextClassName": "cssTextClass" } }* 409 | 410 | ## op.getLineText 411 | #### Syntax 412 | op.getLineText () 413 | 414 | #### Params 415 | None. 416 | 417 | #### Returns 418 | The text on the bar cursor headline. 419 | 420 | #### Example 421 | `op.getLineText ()` 422 | 423 | - *But what is the protocol if the user hits Cancel?* 424 | 425 | ## op.getOutlineJstruct 426 | #### Syntax 427 | op.getOutlineJstruct () 428 | 429 | #### Params 430 | None. 431 | 432 | #### Returns 433 | A JavaScript object representing all the data in the outline. 434 | 435 | This is useful if you want to process the outline in JavaScript code in the most natural way. 436 | 437 | #### Notes 438 | Functionally, this verb does exactly what opml.getCurrentObject does, but this verb should be quite a bit faster for large outlines. 439 | 440 | It's similar to op.getCursorJstruct, which gets the outline structure underneath the bar cursor headline. 441 | 442 | #### Example 443 | `op.getOutlineJstruct ()` 444 | 445 |
{
446 | "head": {
447 | "title": "test",
448 | "dateCreated": "Wed, 07 Apr 2021 16:05:20 GMT",
449 | "dateModified": "Wed, 07 Apr 2021 16:17:01 GMT"
450 | },
451 | "body": {
452 | "subs": [
453 | {
454 | "text": "Hello World",
455 | "created": "Wed, 07 Apr 2021 15:53:15 GMT"
456 | }
457 | ]
458 | }
459 | }
460 |
461 | ## op.getRenderMode
462 | #### Syntax
463 | op.getRenderMode ()
464 |
465 | #### Params
466 | None.
467 |
468 | #### Returns
469 | true if the outline is in render mode, false otherwise.
470 |
471 | #### Example
472 | `op.getRenderMode ()`
473 |
474 | - *true*
475 |
476 | `op.setRenderMode (true)`
477 |
478 | - *undefined*
479 |
480 | ## op.getSelectedText
481 | #### Syntax
482 | op.getSelectedText ()
483 |
484 | #### Params
485 | None.
486 |
487 | #### Returns
488 | The selected text if there is a selection, undefined if there isn't.
489 |
490 | #### See also
491 | op.replaceSelectedText ()
492 |
493 | #### Example
494 | `op.getSelectedText ()`
495 |
496 | - *"Toy Story"*
497 |
498 | ## op.go
499 | #### Syntax
500 | op.go (direction, count)
501 |
502 | #### Params
503 | direction is one of the directions the outliner supports: up, down, left, right, flatup, flatdown, nodirection.
504 |
505 | count is the number of times the cursor will move in the indicated direction.
506 |
507 | #### What it does
508 | It tries to move the bar cursor in the indicated directions, the indicated number of times.
509 |
510 | - *up - bar cursor moves to previous sibling*
511 |
512 | - *down -- bar cursor moves to next sibling*
513 |
514 | - *left -- bar cursor moves to parent*
515 |
516 | - *right -- bar cursor moves to first child, expanding if necessary*
517 |
518 | - *flatup -- bar cursor moves to the previous headline up from the cursor, regardless of level*
519 |
520 | - *flatdown -- bar cursor moves to the next headline down from the cursor, regardless of level*
521 |
522 | #### Returns
523 | true if it was able to move, false otherwise.
524 |
525 | #### Examples
526 | `op.go (left, 1)`
527 |
528 | - *true*
529 |
530 | `op.go (flatdown, 1)`
531 |
532 | - *true*
533 |
534 | `op.go (down, 1)`
535 |
536 | - *false*
537 |
538 | ## op.hasSubs
539 | #### Syntax
540 | op.hasSubs ()
541 |
542 | #### Params
543 | None.
544 |
545 | #### Returns
546 | True if the bar cursor headline has children, false if it doesn't.
547 |
548 | #### Example
549 | `op.hasSubs ()`
550 |
551 | - *true*
552 |
553 | ## op.insertInCalendar
554 | #### Syntax
555 | op.insertInCalendar (string, object)
556 |
557 | #### Params
558 | The string is the text of the headline that will be created.
559 |
560 | The object is a JavaScript object containing the attributes to be attached to the new headline.
561 |
562 | Both params are optional, if the string is not defined we use the empty string, if the object is not defined, we create one with a single attribute, created, containing the current date/.time.
563 |
564 | #### What it does
565 | A new headline is created in the active outline in a calendar structure of months, with days, exactly as the big plus icon does.
566 |
567 | We use the created attribute to determine where in the calendar structure to put the headline.
568 |
569 | #### Returns
570 | undefined.
571 |
572 | #### Examples
573 | `op.insertInCalendar ()`
574 |
575 | - *undefined*
576 |
577 | `op.insertInCalendar ("hello", {color: "blue", age: 22})`
578 |
579 | - *undefined*
580 |
581 | ## op.insertOpml
582 | #### Syntax
583 | op.insertOpml (opmltext, direction)
584 |
585 | #### Params
586 | opmltext is a string containing the text representing an outline to be inserted relative to the bar cursor headline.
587 |
588 | direction indicates where the new headline will go.
589 |
590 | - *up, to create a previous sibling, *
591 |
592 | - *down, to create a next sibling. *
593 |
594 | - *left to create a sibling down from its parent. *
595 |
596 | - *right to create a new first child of the bar cursor headline.*
597 |
598 | #### Returns
599 | true.
600 |
601 | #### Examples
602 | `op.insertOpml ("It's even worse than it appears.
* 708 | 709 | `string.markdownProcess ("I read [Scripting News](http://scripting.com/).")` 710 | 711 | - *I read Scripting News.
* 712 | 713 | `string.markdownProcess ("* one\n* two\n* three\n")` 714 | 715 |